试图找出如何找到与async.eachSeries完全相同的功能的东西,我需要一个按顺序运行的异步动作列表(不是并行)但是找不到在原生ES6中执行它的方法,可以有人建议吗?
P.S。想到发电机/产量,但还没有经验,所以我没有意识到它究竟能帮助我。
修改1
根据请求,这是一个例子:
假设此代码:
let model1 = new MongooseModel({prop1: "a", prop2: "b"});
let model2 = new MongooseModel({prop1: "c", prop2: "d"});
let arr = [model1 , model2];
现在,我想在一系列中运行它,而不是并行,所以使用“async”NPM很容易:
async.eachSeries(arr, (model, next)=>{
model.save.then(next).catch(next);
}, err=>{
if(err) return reject(error);
resolve();
})
我的问题是:使用ES6,我可以原生使用吗?没有NPM'异步'包?
修改2
使用async / await可以轻松完成:
let model1 = new MongooseModel({prop1: "a", prop2: "b"});
let model2 = new MongooseModel({prop1: "c", prop2: "d"});
let arr = [model1 , model2];
for(let model of arr){
await model.save();
}
答案 0 :(得分:45)
对于那些喜欢简短答案的人:
[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());
答案 1 :(得分:14)
假设您想要在数据数组上调用一些异步函数,并且希望它们按顺序调用,而不是并行调用。
async.eachSeries()
的界面如下:
eachSeries(arr, iterator, [callback])
以下是如何使用promises模拟它:
// define helper function that works kind of like async.eachSeries
function eachSeries(arr, iteratorFn) {
return arr.reduce(function(p, item) {
return p.then(function() {
return iteratorFn(item);
});
}, Promise.resolve());
}
这假设iteratorFn
将项目作为参数处理,并且它返回一个promise。
这是一个用法示例(假设您有一个宣传的fs.readFileAsync()
)并且有一个名为speak()
的函数,它在完成后返回一个承诺:
var files = ["hello.dat", "goodbye.dat", "genericgreeting.dat"];
eachSeries(files, function(file) {
return fs.readFileAsync(file).then(function(data) {
return speak(data);
});
});
这使得承诺基础设施可以为您排序。
您也可以手动排序(虽然我不确定原因):
function eachSeries(arr, iteratorFn) {
return new Promise(resolve, reject) {
var index = 0;
function next() {
if (index < arr.length) {
try {
iteratorFn(arr[index++]).then(next, reject);
} catch(e) {
reject(e);
}
} else {
resolve();
}
}
// kick off first iteration
next();
});
}
或者,一个更简单的版本,手动将承诺链接在一起:
function eachSeries(arr, iteratorFn) {
var index = 0;
function next() {
if (index < arr.length) {
return iteratorFn(arr[index++]).then(next);
}
}
return Promise.resolve().then(next);
}
请注意其中一个手动版本必须将iteratorFn()
与try/catch
包围,以确保它是安全的(将异常转换为拒绝)。 .then()
自动安全,因此其他方案不必手动捕获异常,因为.then()
已经为您捕获了异常。
答案 2 :(得分:1)
作为answer provided by @jib的扩展...您还可以将项目数组映射到异步函数,如下所示:
[item1, item2]
.map(item => async (prev_result) => await something_async(item))
.reduce((p, f) => p.then(f), Promise.resolve())
.then(() => console.log('all done'));
请注意prev_result
前一次评估{}返回的值something_async
,这大致相当于async.eachSeries
和async.waterfall
之间的混合。
答案 3 :(得分:0)
您可以通过返回then
回调进行链接。例如:
new Promise(function(resolve, reject){
resolve(1)
}).then(function(v){
console.log(v);
return v + 1;
}).then(function(v){
console.log(v)
});
将打印:
1
2
这当然可以在异步解析承诺时起作用:
new Promise(function(resolve, reject){
setTimeout(function(){
resolve(1);
}, 1000)
}).then(function(result){
return new Promise(function(resolve, reject){
setTimeout(function(){
console.log(result);
resolve(result + 1);
}, 1000)
});
}).then(function(results){
console.log(results);
});
印刷:
1
2
答案 4 :(得分:0)
//为运行较低nodejs版本的系统上传此内容(Azure:/) 不是最短但最好的我能想到的
例如,让我们说&#34; functionWithPromise&#34;返回一些承诺并期待一些项目。functionWithPromise(item);
promisesArray =[];
//syncornized
itemsArray.forEach(function (item){
promisesArray.push(functionWithPromise(item));
});
Promise.all(promisesArray).then(function (values){
//profit
});