【问题标题】:How do you wait to return a value until promise is resolved?在 promise 解决之前,你如何等待返回一个值?
【发布时间】:2016-10-14 10:52:07
【问题描述】:

我正在尝试编写一个函数,它在函数内部的 Promise 解决之前不会返回它的值。这是我正在尝试做的一个简化示例。

'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 直到所有回调都被调用?

我看过很多关于等待的东西。这里有必要吗?非常不希望将其他库添加到我的项目中。

【问题讨论】:

  • 我认为这样做的首选方法是将回调传递给您的函数,该回调将在准备好时调用。
  • 最好还是放弃同步返回值的想法。您的数据库 API 公开了 Promise,因此请按原样使用它们,不要试图使其成为同步的东西。你可以写任何你想坚持异步/承诺模式的东西。这是改变你的观点的问题。

标签: javascript callback promise asynccallback


【解决方案1】:

由于您返回所有配置文件名称的操作也是异步的,因此您应该在所有其他异步操作完成时返回一个 Promise 完成(或在其中一个被拒绝时拒绝)用 Promise.all 完成

function get(db, id) {
  let p = db.command('GET', 'group:${id}');
  return p.then(g => {
    return Promise.all(g.members.map(id => {
      // NOTE: id is shadowing the outer function id parameter
      return User.get(db, id).then(profile => profile.name)
    })
  })
}

【讨论】:

  • 这正是我想要的。谢谢。
【解决方案2】:

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

是的,有。但是你应该改变你的思维方式,从“等到所有的回调都被调用”改为“等到所有的承诺都被实现”。事实上,Promise.all 函数很简单地做到了这一点——它接受一个 promise 数组并返回一个新的 promise,该 promise 用一组结果来解析。

在你的情况下,它会是

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;
         });
    });
}

【讨论】:

    猜你喜欢
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 2017-02-10
    • 1970-01-01
    • 2015-05-09
    相关资源
    最近更新 更多