Ответ 1
Для тех, кто любит короткие ответы:
[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());
Попытка выяснить, как найти что-то, что функционирует точно так же, как 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];
Теперь я хочу запустить его в серии, а не параллельно, поэтому с "асинхронным" NPM это легко:
async.eachSeries(arr, (model, next)=>{
model.save.then(next).catch(next);
}, err=>{
if(err) return reject(error);
resolve();
})
Мой вопрос: с ES6, могу ли я сделать это изначально? без пакета async 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();
}
Для тех, кто любит короткие ответы:
[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());
Скажем, вы хотите вызвать некоторую асинхронную функцию в массиве данных, и вы хотите, чтобы их вызывали последовательно, а не параллельно.
Интерфейс для 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
принимает элемент для обработки в качестве аргумента и возвращает его.
Здесь приведен пример использования (который предполагает, что у вас есть обещанный 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();
});
}
Или более простая версия, которая вручную объединяет promises:
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()
уже улавливает их для вас.
Вы можете цепью, возвращаясь в обратном вызове 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
Это, конечно, работает при асинхронном разрешении promises:
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
//Загружая это для систем, которые запускают более низкую версию nodejs (Azure:/) Не самый короткий, но самый красивый, о котором я могу думать
например, скажем, "functionWithPromise" возвращает некоторые обещания и ожидает какой-то элемент.
functionWithPromise(item);
promisesArray =[];
//syncornized
itemsArray.forEach(function (item){
promisesArray.push(functionWithPromise(item));
});
Promise.all(promisesArray).then(function (values){
//profit
});