D
D
DarthJS2018-02-01 01:45:46
JavaScript
DarthJS, 2018-02-01 01:45:46

How to correctly wait for the result of asynchronous functions in a chain of calls?

For example, there is a constructor:
function Foo () {
this.results = [];
}
//
Foo.prototype.tick = function (callback) {
callback(function (data) {
Promise.resolve(this.results.push(data));
});
return this;
}
Foo.prototype.finish = function () {
this.wait().then(function (response) {
console.log(response) // second, first
})
}
//
function callBackFooFirst (cb) {
setTimeour(cb, 4000, 'first')
}
function callBackFooSecond (cb) {
setTimeour(cb, 1000, 'second')
}
// And the actual call
var test = new Foo();
test
.tick(callBackFooFirst)
.tick(callBackFooSecond)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2018-02-01
@DarthJS

It is possible like this:

class Foo {
  constructor() {
    this.queue = [];
  }

  tick(cb) {
    this.queue.push(cb);
    return this;
  }

  then(cb) {
    return this.queue.reduce((acc, fn) =>
      acc.then(fn), Promise.resolve()).then(cb);
  }
}

Prototype style variant:
function Foo() {
  this.queue = [];
}

Foo.prototype.tick = function(cb) {
  this.queue.push(cb);
  return this;
}

Foo.prototype.then = function(cb) {
  return this.queue.reduce(function(acc, fn) {
    return acc.then(fn);
  }, Promise.resolve()).then(cb);
}

Usage example:
const foo = new Foo();

const task1 = () =>
  new Promise(resolve => {
    setTimeout(() => {
      console.log('task1');
      resolve('Done!');
    }, 1000);
  });

const task2 = arg =>
  new Promise(resolve => {
    setTimeout(() => {
      console.log('task2');
      resolve(arg);
    }, 1000);
  });

foo.tick(task1)
   .tick(task2)
   .then(console.log);

/* result:

    task1
    task2
    Done!

*/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question