节点promises.all()不按预期方式工作
我试图在使用promise.all()
循环后同步运行一个函数列表,但我的代码不能按预期方式工作。
有人知道我做错了什么吗?
我的代码是:
var Promise = require('promise'); var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.all(promises) .then(function (data) { console.log("done"); }); function foo(i) { return new Promise(function (resolve, reject) { console.log('---> foo i ' + i); resolve('done foo ' + i); }); }
但输出是
push promise 0 ---> foo i 0 push promise 1 ---> foo i 1 push promise 2 ---> foo i 2 done
我期待的地方
push promise 0 push promise 1 push promise 2 ---> foo i 0 ---> foo i 1 ---> foo i 2 done
先谢谢你。
这里发生的是,当你调用promise构造函数时,传递给它的函数在施工调用期间被调用。 如果您在承诺(这是预期的用例)内有asynchronous调用,那么它会创build您期望的行为。
这里是我的示例代码,使用setTimeout
作为asynchronous调用,并注意如何在asynchronouscallback中进行resolve
调用。
var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.all(promises) .then(function (data) { console.log("done"); }); function foo(i) { return new Promise(function (resolve, reject) { // The async call is made inside the Promise setTimeout(()=> { console.log('---> foo i ' + i); // And the resolve call is made inside the callback function resolve('done foo ' + i); }); }); }
如果你运行这个,你应该得到你想要的输出(用chrometesting):
push promise 0 push promise 1 push promise 2 ---> foo i 0 ---> foo i 1 ---> foo i 2 done
附录:这只适用于( foo i 0, ... 1 ... 2
),因为这些请求都是一个接一个地立即完成的。 如果是ajax调用,foo语句将按照完成顺序打印。 所以如果请求2在0或1之前完成,你会先看到foo i 2
。 但是只有当所有的请求都被解决后才能看到。
我试图在使用promise.all()循环后同步运行一个函数列表,但我的代码不能按预期方式工作。
我想你想同步运行一个function列表。 如果是这样,我推荐使用Bluebird Promise.each()
。
var Promise = require('bluebird'); var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.each(promises, function(result) { console.log(result); }); function foo(i) { return new Promise(function (resolve, reject) { resolve('done foo ' + i); }); }
结果:
push promise 0 push promise 1 push promise 2 done foo 0 done foo 1 done foo 2
你的console.log('---> foo i ' + i);
因为它在resolve
方法之外,所以在创buildpromise时执行了这一行,而是在您提供给Promise
构造函数的executor函数中执行。
这应该给你你的预期输出
var Promise = require('promise'); var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.all(promises) .then(function (data) { for (var i = 0; i < data.length; i++) { console.log(data[i]); } console.log("done"); }); function foo(i) { return new Promise(function (resolve, reject) { resolve('--> foo i ' + i); }); }