Javascript 在承诺得到解决之前,如何等待返回值?

Javascript 在承诺得到解决之前,如何等待返回值?,javascript,callback,promise,asynccallback,Javascript,Callback,Promise,Asynccallback,我试图编写一个函数,在函数内部的承诺得到解决之前,它不会返回它的值。这里有一个简单的例子来说明我要做的事情 'use strict'; function get(db, id) { let p = db.command('GET', 'group:${id}'); p.then(g => { g.memberNames = []; g.members.forEach(id => { User.get(

我试图编写一个函数,在函数内部的承诺得到解决之前,它不会返回它的值。这里有一个简单的例子来说明我要做的事情

'use strict';

function get(db, id) {
     let p = db.command('GET', 'group:${id}');
     p.then(g => {
         g.memberNames = [];
         g.members.forEach(id => {
             User.get(db, id)
                 .then(profile => g.memberNames.push(profile.name))
                 .catch(err => reject(err));
         });
         return g;
    });
}
它是一个请求组id并返回该组数据的函数。在此过程中,它还将用户名插入数据结构,以显示用户名而不是用户id。我的问题是,这是异步运行的,将跳过.then回调。当它返回g时,没有调用任何回调,
g.memberNames
仍然为空。有没有办法让函数等待返回g,直到调用完所有回调


我看过很多关于等待的东西。这里有必要吗?向我的项目中添加其他库是非常不可取的。

因为返回所有配置文件名称的操作也是异步的,所以在完成所有其他异步操作(或拒绝其中一个操作时拒绝)时,您应该返回一个已实现的承诺

有没有办法让函数等待返回
g
,直到调用完所有回调

是的,有。但是你应该改变你的思维方式,从“等到所有的回调都被调用”到“等到所有的承诺都实现”。事实上,这个函数很容易做到这一点——它接受一个承诺数组并返回一个新的承诺,该承诺用一个结果数组进行解析

在你的情况下,应该是

function get(db, id) {
     return db.command('GET', 'group:${id}').then(g => {
         var promises = g.members.map(id => {
//                                ^^^ never use `forEach`
             return User.get(db, id).then(profile => profile.name);
//           ^^^^^^ a promise for the name of that profile
         });
         //
         return Promise.all(promises).then(names => {
//                                    ^^^^^^^^^^ fulfills with an array of the names
             g.memberNames = names;
             return g;
         });
    });
}

我认为最好的方法是向你的函数传递一个回调函数,在准备好的时候调用它。最好放弃同步返回值的想法。您的数据库API正在公开承诺,所以请将其作为承诺使用,不要试图将其变成同步的东西。您可以按照异步/承诺模式编写任何需要的内容。这是改变你观点的问题。这正是我想要的。非常感谢。
function get(db, id) {
     return db.command('GET', 'group:${id}').then(g => {
         var promises = g.members.map(id => {
//                                ^^^ never use `forEach`
             return User.get(db, id).then(profile => profile.name);
//           ^^^^^^ a promise for the name of that profile
         });
         //
         return Promise.all(promises).then(names => {
//                                    ^^^^^^^^^^ fulfills with an array of the names
             g.memberNames = names;
             return g;
         });
    });
}