在Promise.then函数中不会更改外部variables

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

在另一个地方,它是有效的,只是没有Promise.thenfunction。 为什么这不起作用?

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 

Promise代表任务未来的结果 。 在这种情况下,您在任务(对Item.get的调用)完成工作之前正在loggingfixedItems 。 换句话说, then函数还没有运行,所以什么也没有被放入到fixedItems

如果您想要在包含所有项目的情况下使用fixedItems ,则需要等待所有的承诺才能解决。

你怎么做取决于你正在使用的Promise库。 这个例子和Promise.all ,可以和许多库一起工作,包括原生的ES6 Promise.all

 // 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的岩石介绍承诺 。

你的问题是,在循环中的任何promise都执行完之前,你正在调用console.log(fixedItems) 。 解决asynchronous问题的一个更好的方法是将所有的项目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 } 

我很难find如何查找多个logging在一个单一的查询ID与思维,但我确实发现这个网页可能有所帮助: http : //c2journal.com/2013/01/17/rethinkdb-filtering-for -multiple的IDS /

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

更新:或者对于后面的选项,你可以在上面的joews的回答中使用代码。

Interesting Posts