1

在节点上使用 thinky.js 时,我试图遍历一个循环并将每个项目添加到一个数组中。但是,由于某种原因,这不起作用。

在另一个地方,它是相同的并且可以工作,只是没有 Promise.then 函数。为什么这不起作用?

var fixedItems = [];
for (i in tradeItems) {
  var item = tradeItems[i];
  Item.get(item["id"]).run().then(function(result) {
    var f = { "assetid": result["asset_id"] };
    console.log(f);  // WOrks
    fixedItems.push(f); // Doesn't work
  });
}

console.log(fixedItems); // Nothing

4

2 回答 2

2

Promise 代表任务的未来结果。在这种情况下,您是fixedItems在您的任务(对 的调用Item.get)完成工作之前记录的。换句话说,这些then函数还没有运行,所以没有任何东西被放入fixedItems.

如果你想fixedItems在它包含所有项目时使用它,你需要等待所有的 Promise 解决。

你如何做到这一点取决于你使用的 Promise 库。这个带有 的示例Promise.all适用于许多库,包括本机 ES6 Promises:

// Get an array of Promises, one per item to fetch.
// The Item.get calls start running in parallel immediately.
var promises = Object.keys(tradeItems).map(function(key) {
  var tradeItem = tradeItems[key];
  return Item.get(tradeItem.id);
});

// Wait for all of the promises to resolve. When they do,
//  work on all of the resolved values together.
Promise.all(promises)
  .then(function(results) {
    // At this point all of your promises have resolved.
    // results is an array of all of the resolved values.

    // Create your fixed items and return to make them available
    //  to future Promises in this chain
    return results.map(function(result) {
      return { assetid: result.asset_id }
    });
  })
  .then(function(fixedItems) {
    // In this example, all we want to do is log them
    console.log(fixedItems);
  });

推荐阅读:HTML5 摇滚介绍 Promises

于 2015-10-18T12:28:40.810 回答
1

您的问题是您console.log(fixedItems)在循环中的任何承诺完成执行之前调用。一个更好的解决异步问题的方法是首先将所有项目 ID 放在一个数组中,然后在单个查询中检索所有项目,这在数据库端也更有效。

var itemIds = tradeItems.map(function(item) {
    return item.id;
});

var fixedItems = [];

//you would need to write your own getItemsById() function or put the code
//to get the items here
getItemsById(itemIds).then(function(items) {

    items.forEach(function(item) {
        var f = { "assetid": result["asset_id"] };
        fixedItems.push(f);
    });

    whenDone();
});

function whenDone() {
    //you should be able to access fixedItems here
}

我无法轻松找到如何在一个使用 thinky 的查询中按 ID 查找多条记录,但我确实找到了这个可能有帮助的页面: http: //c2journal.com/2013/01/17/rethinkdb-filtering-for -multiple-ids/

虽然这将是我解决此问题的首选方式,但仍然可以使用多个查询并使用承诺链等待它们全部解决,然后再继续执行后续代码。如果您想走这条路,请查看此链接: http: //promise-nuggets.github.io/articles/11-doing-things-in-parallel.html。(注意:我没有亲自使用过 Bluebird,但我认为该链接中的 Bluebird 示例可能已过时。该map方法似乎是当前推荐使用 promise 执行此操作的方法:https ://stackoverflow.com/a /28167340/560114。)

更新:或者对于后一种选择,您可以只使用上面 joews 答案中的代码。

于 2015-10-18T12:28:07.697 回答