Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute an Array of promises sequentially without using async/await

Lets say I have an array of promises. Each element of my array is a knex.js query builder and is ready to be executed and returns a promise.

How can I run each element of this array sequentially. The array is built dynamically.

let promisesArray = [q1,q2,q3] ;

Each q is not a promise by itself but it will return a promise upon execution.

like image 476
Salar Avatar asked Apr 25 '19 08:04

Salar


People also ask

How do you execute a promise in a sequence?

The essence of this function is to use reduce starting with an initial value of Promise. resolve([]) , or a promise containing an empty array. This promise will then be passed into the reduce method as promise . This is the key to chaining each promise together sequentially.

Can we use promise without await?

Because async functions are Promises under the hood, we can run both asyncThing1() and asyncThing2() in parallel by calling them without await . Then we can use await and Promise. all , which returns an array of results once all Promises have completed.

How do you run multiple promises together?

Approach 1: In this approach, we will use Promise. all() method which takes all promises in a single array as its input. As a result, this method executes all the promises in itself and returns a new single promise in which the values of all the other promises are combined together.

Can we use promise without async?

Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.


2 Answers

Here could be a possible option:

let p = Promise.resolve([]);
promisesArray.forEach(q => {
  p = p.then(responses => {
    //based on the nature of each q, to start execution
    //use either q().then() or q.then()
    return q().then(response => {
      //Any further logic can be here.
      console.log(response);
      return responses.concat([response]);
    })
  })
})

p.then(responses => {
  // here you have all of the responses.
})
like image 104
Amin Fazlali Avatar answered Nov 13 '22 12:11

Amin Fazlali


You can use Array.reduce to reduce the Array into one promise that chains them one after another

let promisesArray = [q1,q2,q3] ;

function runSequentially(promiseArr) {
  return promiseArr.reduce((accum, p) => accum.then(p), Promise.resolve())
}

//Example, this prints.. 1, 2, 3 then "done".
runSequentially([Promise.resolve(1).then(console.log), Promise.resolve(2).then(console.log), Promise.resolve(3).then(console.log)]).then(() => console.log("done"))
like image 20
Khaled Osman Avatar answered Nov 13 '22 14:11

Khaled Osman