Plyto
Plyto

Reputation: 751

Promise loops (bluebird) - wrap object in async

I have a question about promises.

I am using Bluebird Promise library and build a small async library with it.

I am trying to waterfall promises with the use of a function.

Say I use promises like so:

Promise.resolve()
.then(function () {
  console.log("called 1")
  return 1;
}).then(function () {
  return new Promise (function (res, rej) {
    setTimeout(function () {
      console.log("called 2")
      res(2);  
    }, 1500);
  });
}).then(function () {
  console.log("called 3")
  return 3;
});

This does in fact wait in a loop and return 1,2,3 in order.

How do I wrap it into a function so that I can do something like this:

a();b();c();, or a().b().c(); where a() puts something onto a chain, b() puts something onto a chain, and c() puts something onto a chain in order.

Since then() returns a new promise, it can all go out of order, so something like does not work:

var promise = Promise.resolve();
function a () {
  promise.then(function () { 
    // do sync/async 
  });
}
function b () {
  promise.then(function () {
    //do sync/async
  });
}
function c ...

Thank you for your time :]

I'm not sure what the goal is here. Do you want to have an arbitrary number of things run in sequence where the sequence is known in advance? Or is this a case where the sequence is discovered as you go? The NodeJS streams interface is a lot better for processing an unknown number of things sequentially (@tadman)

Sequence is discoverable, goal is to have ability to call a().b().c() or b().a().d(). Async library on a client-side.

Update: If I do as @zerkms says it does not work as expected. My bad, should work ok, but with lack of context/code did not give me enough info to expand on. Still thank you for your answer, as it gave me more food for thought.

Update: See my answer

Upvotes: 0

Views: 385

Answers (2)

Plyto
Plyto

Reputation: 751

Thanks to @tadman I came up with this so far, seems to work as I expect it to. The problem was that I did not update the promise before calling then on it, and it was branching instead of calling it in sequence. And this is what I wanted - to turn an object that has both sync/async into async to allow chaining. Petka (@Esailija) also shows great example of building DSLs above (semvar version bumping & git pushing) by extending bluebird library, but for my purposes this is enough.

var Sample = function () {
  this.promise = Promise.resolve();
};

Sample.prototype.a = function () {
  this.then(function () {
    console.log("1");
  });
  return this;
};

Sample.prototype.b = function () {
  this.then(function () {
    return new Promise(function (res, rej) {
      setTimeout(function() {
        console.log("2");
        res();
      }, 500);
    });
  });
  return this;
};

Sample.prototype.c = function () {
  this.then(function () {
    console.log("3");
  })
  return this;
};

Sample.prototype.chainPromise = function (func) {
  this.promise = this.promise.then(func);
};

var s = new Sample();
s.a().b().c();

or even then instead of chainPromise?

Sample.prototype.then = function (func) {
  this.promise = this.promise.then(func);
  return this.promise;
};

Upvotes: 0

Esailija
Esailija

Reputation: 140228

You could use a scoped prototype and just add those methods there

Promise.prototype.a = function() {
  return this.then(function() {
    console.log("called 1")
    return 1;
  });
};

Promise.prototype.b = function() {
  return this.delay(1500).then(function() {
    console.log("called 2")
    return 1;
  });
};

Promise.prototype.c = function() {
  return this.then(function() {
    console.log("called 3")
    return 3;
  });
};

I use this to create neat DSLs e.g. with git:

https://gist.github.com/petkaantonov/6a73bd1a35d471ddc586

Upvotes: 1

Related Questions