Подтвердить что ты не робот

ES6 Promises - что-то вроде async.each?

Попытка выяснить, как найти что-то, что функционирует точно так же, как 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();
}
4b9b3361

Ответ 1

Для тех, кто любит короткие ответы:

[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());

Ответ 2

Скажем, вы хотите вызвать некоторую асинхронную функцию в массиве данных, и вы хотите, чтобы их вызывали последовательно, а не параллельно.

Интерфейс для 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() уже улавливает их для вас.

Ответ 3

Вы можете цепью, возвращаясь в обратном вызове 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

Ответ 4

//Загружая это для систем, которые запускают более низкую версию nodejs (Azure:/) Не самый короткий, но самый красивый, о котором я могу думать

например, скажем, "functionWithPromise" возвращает некоторые обещания и ожидает какой-то элемент.

functionWithPromise(item);

promisesArray =[];

//syncornized
itemsArray.forEach(function (item){
   promisesArray.push(functionWithPromise(item));
});

Promise.all(promisesArray).then(function (values){
//profit
});