Skip to content

Instantly share code, notes, and snippets.

@anvk
Last active October 11, 2023 09:02
Show Gist options
  • Save anvk/5602ec398e4fdc521e2bf9940fd90f84 to your computer and use it in GitHub Desktop.
Save anvk/5602ec398e4fdc521e2bf9940fd90f84 to your computer and use it in GitHub Desktop.
Sequential execution of Promises using reduce()
function asyncFunc(e) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(e), e * 1000);
});
}
const arr = [1, 2, 3];
let final = [];
function workMyCollection(arr) {
return arr.reduce((promise, item) => {
return promise
.then((result) => {
console.log(`item ${item}`);
return asyncFunc(item).then(result => final.push(result));
})
.catch(console.error);
}, Promise.resolve());
}
workMyCollection(arr)
.then(() => console.log(`FINAL RESULT is ${final}`));
@empz
Copy link

empz commented Dec 1, 2018

Using reduce for this makes it harder than it has to be. It's not very easy on the eyes and mind.
I'd prefer something like this if await / async is available.

// functions is an array of functions that return a promise.
async function runInSequence(functions) {
  const results = [];

  for (const fn of functions) {
    results.push(await fn());
  }

  return results;
}

And we can use it like this:

function promisedFunction(delay, value) {
  return new Promise(resolve => {
    setTimeout(() => resolve(value), delay);
  });
}

console.time("execution");
const results = await runInSequence([
  promisedFunction.bind(this, 1000, 1),
  promisedFunction.bind(this, 1000, 2),
  promisedFunction.bind(this, 1000, 3)
]);

console.timeEnd("execution"); // execution: 3000 ms (approx)
console.log(results); // [1, 2, 3]

@robertoandres24
Copy link

Thanks. Helped me a lot to solution duplicate primary key constraint in save() method with Typeform. The parallel process was my issue and I changed my Promise.all( ) loop, for this fn, and it works great.

@juanccamachob94
Copy link

My pay:

class TasksService {
  static async execute(context, tasks) {
    let results = [];
     await tasks.reduce((promise, task) => {
      return promise
        .then((result) => {
          return TasksService.asyncFunc(task).then(r => {
            results.push(r.bind(context)())
          });
        })
    }, Promise.resolve());
    return results;
  }

  static asyncFunc(f) {
    return new Promise((resolve, reject) => {
      let task = f;
      let time = 0;
      if(typeof(task) !== 'function') {
        task = f.task;
        time = f.time;
      }
      setTimeout(() => resolve(task), time);
    });
  }
}

module.exports = TasksService;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment