Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 Promises - something like async.each?

Trying to figure-out how to find something that functional exactly like async.eachSeries, i need a list of async actions run in sequence (not in parallel) but can't find a way to do it in native ES6, can anyone advise, please?

p.s. thought about generators/yield but don't have the experience yet so I'm not realized how exactly it can help me.

Edit 1

per request, here is an example:

Assume this code:

let model1 = new MongooseModel({prop1: "a", prop2: "b"}); let model2 = new MongooseModel({prop1: "c", prop2: "d"});  let arr = [model1 , model2]; 

Now, I want to run over it in a series, not parallel, so with the "async" NPM it's easy:

async.eachSeries(arr, (model, next)=>{     model.save.then(next).catch(next); }, err=>{     if(err) return reject(error);     resolve(); }) 

My question is: with ES6, can I do it natively? without the NPM 'async' package?

Edit 2

With async/await it can be done easily:

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(); } 
like image 690
Shlomi Avatar asked Aug 15 '15 19:08

Shlomi


People also ask

Are promises asynchronous?

A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.

Is async await the same as promises?

1. Promise is an object representing intermediate state of operation which is guaranteed to complete its execution at some point in future. Async/Await is a syntactic sugar for promises, a wrapper making the code execute more synchronously.

Is ES6 asynchronous?

ES6 makes asynchronous programming easier with the async and await keywords.

What are ES6 promises?

Promises are a way to implement asynchronous programming in JavaScript(ES6 which is also known as ECMAScript-6). A Promise acts as a container for future values.


2 Answers

For those who like short answers:

[func1, func2].reduce((p, f) => p.then(f), Promise.resolve()); 
like image 193
jib Avatar answered Sep 20 '22 22:09

jib


Let's say you want to call some async function on an array of data and you want them called sequentially, not in parallel.

The interface for async.eachSeries() is like this:

eachSeries(arr, iterator, [callback]) 

Here's how to simulate that with 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()); } 

This assumes that iteratorFn takes the item to process as an argument and that it returns a promise.

Here's a usage example (that assumes you have a promisified fs.readFileAsync()) and have a function called speak() that returns a promise when done:

 var files = ["hello.dat", "goodbye.dat", "genericgreeting.dat"];  eachSeries(files, function(file) {      return fs.readFileAsync(file).then(function(data) {          return speak(data);      });  }); 

This lets the promise infrastructure sequence everything for you.


It is also possible for you to sequence things manually (though I'm not sure why):

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();     }); } 

Or, a simpler version that manually chains the promises together:

function eachSeries(arr, iteratorFn) {     var index = 0;      function next() {         if (index < arr.length) {             return iteratorFn(arr[index++]).then(next);         }     }     return Promise.resolve().then(next); } 

Note how one of the manual versions has to surround iteratorFn() with try/catch in order to make sure it is throw-safe (convert exceptions into a rejection). .then() is automatically throw safe so the other schemes don't have to manually catch exceptions since .then() already catches them for you.

like image 35
jfriend00 Avatar answered Sep 16 '22 22:09

jfriend00