如何正确构造循环以确保满足以下条件承诺电话和被束缚的记录器.log(res)通过迭代同步运行? (蓝鸟)
db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise
我尝试了以下方法(方法来自http://blog.victorquinn.com/javascript-promise-while-loop http://blog.victorquinn.com/javascript-promise-while-loop )
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
});
var count = 0;
promiseWhile(function() {
return count < 10;
}, function() {
return new Promise(function(resolve, reject) {
db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
resolve();
});
});
}).then(function() {
console.log('all done');
});
虽然看起来可行,但我认为它不能保证调用的顺序记录器.log(res);
有什么建议么?
如果你真的想要一个将军promiseWhen()
函数用于此目的和其他目的,那么一定要使用 Bergi 的简化来实现。然而,由于 Promise 的工作方式,以这种方式传递回调通常是不必要的,并且会迫使您跳过复杂的小圈子。
据我所知你正在尝试:
- 异步获取电子邮件地址集合的一系列用户详细信息(至少,这是唯一有意义的场景)。
- 通过建立一个
.then()
通过递归链。
- 处理返回结果时保持原来的顺序。
如此定义,问题实际上是在“The Collection Kerfuffle”中讨论的问题Promise 反模式 http://taoofcode.net/promise-anti-patterns/,它提供了两个简单的解决方案:
- 并行异步调用使用
Array.prototype.map()
- 串行异步调用使用
Array.prototype.reduce()
.
并行方法将(直接)给出您试图避免的问题 - 响应的顺序不确定。串行方法将构建所需的.then()
链 - 扁平 - 无递归。
function fetchUserDetails(arr) {
return arr.reduce(function(promise, email) {
return promise.then(function() {
return db.getUser(email).done(function(res) {
logger.log(res);
});
});
}, Promise.resolve());
}
调用方式如下:
//Compose here, by whatever means, an array of email addresses.
var arrayOfEmailAddys = [...];
fetchUserDetails(arrayOfEmailAddys).then(function() {
console.log('all done');
});
正如你所看到的,不需要丑陋的外部变量count
或者它是相关的condition
功能。限制(问题中为 10)完全由数组的长度决定arrayOfEmailAddys
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)