【问题标题】:Asyncronously mapping over a collection with a function that returns a promise使用返回承诺的函数异步映射集合
【发布时间】:2016-07-02 19:21:09
【问题描述】:

我正在尝试学习如何使用 Bluebird 承诺,但我有点迷茫。

我有两个数据库表:topic 和 subject。

topic 表有一个subject_id 列,然后可用于查询subject 表的主题标题。

我有一个orm,它异步查询并返回一个承诺。

最终,我正在尝试为主题编写一个模型方法来为您进行查找,将从后续 subject 查询返回的 subject_title 注入到最初从 topic 返回的对象数组中的每个元素中询问。

我正在尝试使用Promise.map,但这不起作用。下面的代码不起作用。我从没想过会这样,但我认为它抓住了我想要完成的事情的本质。

var promise = orm.select({
    db:     db, 
    table:  'topic',  
    where:  args.where,
    order:  args.order,
    limit:  args.limit,
    offset: args.offset,
    group:  args.group
}).map(function (topic) {
    var promise = orm.select({
        db: db,
        table: 'subject',
        qrm: 'one',
        where: {id: topic.subject_id}
    }).then(function (subject) {
        topic.subject_title = subject;
    });
    return promise;
});

return promise;

所以,假设一个普通的topic 对象具有以下属性:

[subject_id, title, description]

subject 对象有:

[id, title]

我希望上述函数返回具有以下属性的对象数组:

[subject_id, subject_title, title, description] 

完成此任务的最简洁方法是什么?

【问题讨论】:

  • 为什么不避免突变并使用您的新属性返回一个新对象?
  • orm.select() 返回什么?它是在回报蓝鸟的承诺吗?以及,什么是履行的数据?
  • @jfriend00 它返回一个蓝鸟承诺。填充的数据是一个对象数组。数组中的每个对象代表topics 表中的一行。
  • @elclanrs 我没有理由更喜欢突变而不是返回一个新数组。无论是最简单的。

标签: javascript asynchronous promise bluebird


【解决方案1】:

看来您只需要从您的 .then() 处理程序返回修改后的 topic 对象,以便它保持已完成的值:

return orm.select({
    db:     db, 
    table:  'topic',  
    where:  args.where,
    order:  args.order,
    limit:  args.limit,
    offset: args.offset,
    group:  args.group
}).map(function (topic) {
    return orm.select({
        db: db,
        table: 'subject',
        qrm: 'one',
        where: {id: topic.subject_id}
    }).then(function (subject) {
        topic.subject_title = subject;
        // Add return here so topic stays the fulfilled value
        return topic;
    });
});

顶级promise的完整值应该是一个修改过的主题对象数组。

【讨论】:

  • 哦!你是对的,这行得通。我假设我最终会得到一系列承诺而不是一系列结果。 map 函数如何知道要等待所有的承诺都被履行,直到自己履行?
  • @LukeP - 这就是 Bluebird 承诺中的 .map() 所做的。这只是通过迭代数组然后调用Promise.all() 来收集一组承诺的捷径,这显然会等待您传递的所有承诺,然后再解决它的主承诺。 bluebird doc for .map() 解释得很好。
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
相关资源
最近更新 更多