在使用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
答案 0 :(得分:2)
承诺代表任务的未来结果。在这种情况下,您需要在任务(对fixedItems
的调用)完成之前重新记录Item.get
。换句话说,then
函数还没有运行,所以没有任何内容被放入fixedItems
。
如果您希望在包含所有项目后使用fixedItems
,则需要等待所有承诺解决。
你如何做到这一点取决于你正在使用的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);
});
答案 1 :(得分: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/
虽然这是我解决此问题的首选方法,但在继续使用后续代码之前,还可以使用多个查询并使用promise链等待所有问题得到解决。如果您想要走这条路线,请查看以下链接:http://promise-nuggets.github.io/articles/11-doing-things-in-parallel.html。 (注意:我还没有亲自使用Bluebird,但我认为该链接中的Bluebird示例可能已过时。map
方法似乎是当前推荐的使用promises执行此操作的方法:{{ 3}}。)
更新:或者对于后一种选择,您只需使用上面joews的答案中的代码。