async.mapLimit 承诺
async.mapLimit with Promise
我正在尝试使用异步模块 (v3),尤其是 async.mapLimit 方法来提交有限数量的并行异步请求。这适用于以下(简化的)示例代码中的回调:
async = require('async');
async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
setTimeout(function(){
num = num * 2,
console.log(num);
callback(null, num);
},
4000);
},function(err, results){
console.log(results);
});
结果我得到了单个值,最后得到了包含所有值的数组 'results':
[2,4,6,8,10]
现在我正在苦苦挣扎的是使用此方法的基于 Promise 的版本。如果我不提供回调,The documentation 说它 returns 是一个 Promise。如何将此基于回调的代码更改为使用 Promises?
我尝试过,例如这个,但它只显示了第一组请求(这是在评论中的第一个建议之后更新的):
let numPromise = async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
setTimeout(function(){
num = num * 2,
console.log(num);
callback(null, num);
},
4000);
});
Promise.all([numPromise]) //always calls .then immediately, without result
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));
我确实正确地取回了所有单个值,但是 '.then' 立即执行并给我 'Success' 一个空的 'result' 变量。
注意:我当然看过这个帖子 ES6 Promise replacement of async.eachLimit / async.mapLimit,但我认为这不能回答我的问题。
PS:我已经找到了这个问题的其他解决方案,但我真的很想知道如何正确使用这个模块(使用简短、干净的代码)。
解决方案非常简单 - 虽然我仍然相信上面的代码应该可以工作(根据文档),但我发现还有另一个包是为 promises 而构建的:'promise-async'
所以我替换了行
async = require('async');
与
async = require('promise-async');
现在上面的代码按预期运行:
let numPromise = async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
setTimeout(function(){
num = num * 2,
console.log(num);
callback(null, num);
},
4000);
})
//Promise.all([numPromise]) //Promise.all is not needed
numPromise
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));
Returns
2
4
6
8
10
success:2,4,6,8,10
这可能是更好的答案,尽管另一个选择似乎也不错:
const async = require('async');
const delay = require('util').promisify(setTimeout);
const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
// or const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => {
// await delay(200);
// return num*2;
// })
numPromise.then(console.log)
// or numPromise.then((results) => console.log(results))
另请参阅 GitHub 上的此问题线程作为参考:
GitHub: async.mapLimit does not return a Promise
我认为我的代码的问题出在 iteratee 函数中 - 要么最初它不是异步的,要么使用 'callback' 而不是 'return' 我假设(或者可能两者都 ;-) )。
我正在尝试使用异步模块 (v3),尤其是 async.mapLimit 方法来提交有限数量的并行异步请求。这适用于以下(简化的)示例代码中的回调:
async = require('async');
async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
setTimeout(function(){
num = num * 2,
console.log(num);
callback(null, num);
},
4000);
},function(err, results){
console.log(results);
});
结果我得到了单个值,最后得到了包含所有值的数组 'results':
[2,4,6,8,10]
现在我正在苦苦挣扎的是使用此方法的基于 Promise 的版本。如果我不提供回调,The documentation 说它 returns 是一个 Promise。如何将此基于回调的代码更改为使用 Promises?
我尝试过,例如这个,但它只显示了第一组请求(这是在评论中的第一个建议之后更新的):
let numPromise = async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
setTimeout(function(){
num = num * 2,
console.log(num);
callback(null, num);
},
4000);
});
Promise.all([numPromise]) //always calls .then immediately, without result
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));
我确实正确地取回了所有单个值,但是 '.then' 立即执行并给我 'Success' 一个空的 'result' 变量。
注意:我当然看过这个帖子 ES6 Promise replacement of async.eachLimit / async.mapLimit,但我认为这不能回答我的问题。
PS:我已经找到了这个问题的其他解决方案,但我真的很想知道如何正确使用这个模块(使用简短、干净的代码)。
解决方案非常简单 - 虽然我仍然相信上面的代码应该可以工作(根据文档),但我发现还有另一个包是为 promises 而构建的:'promise-async'
所以我替换了行
async = require('async');
与
async = require('promise-async');
现在上面的代码按预期运行:
let numPromise = async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
setTimeout(function(){
num = num * 2,
console.log(num);
callback(null, num);
},
4000);
})
//Promise.all([numPromise]) //Promise.all is not needed
numPromise
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));
Returns
2
4
6
8
10
success:2,4,6,8,10
这可能是更好的答案,尽管另一个选择似乎也不错:
const async = require('async');
const delay = require('util').promisify(setTimeout);
const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
// or const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => {
// await delay(200);
// return num*2;
// })
numPromise.then(console.log)
// or numPromise.then((results) => console.log(results))
另请参阅 GitHub 上的此问题线程作为参考: GitHub: async.mapLimit does not return a Promise
我认为我的代码的问题出在 iteratee 函数中 - 要么最初它不是异步的,要么使用 'callback' 而不是 'return' 我假设(或者可能两者都 ;-) )。