-1

Let's say I have some code that looks like this:

var doSomething = function(parameter){
    //send some data to the other function
    return when.promise(function(resolveCallback, rejectCallback) {
        var other = doAnotherThing(parameter);
        //how do I check and make sure that other has resolved
        //go out and get more information after the above resolves and display

    }); 
};

var doAnotherThing = function(paramers){
    return when.promise(function(resolveCallback, rejectCallback) {
        //go to a url and grab some data, then resolve it
        var s = "some data I got from the url";
        resolveCallback({
            data: s
        });
    });
};

How do I ensure that var other has completely resolved before finishing and resolving the first doSomething() function? I'm still wrapping my head around Nodes Async characteristic

I really didn't know how else to explain this, so I hope this makes sense! Any help is greatly appreciated

EDIT: In this example, I am deleting things from an external resource, then when that is done, going out the external resource and grabbing a fresh list of the items.

UPDATED CODE

var doSomething = function(parameter){
        //send some data to the other function
        doAnotherThing(parameter).then(function(){
            //now we can go out and retrieve the information
        });
    };

var doAnotherThing = function(paramers){
    return when.promise(function(resolveCallback, rejectCallback) {
        //go to a url and grab some data, then resolve it
        var s = "some data I got from the url";
        resolveCallback({
            data: s
        });
    });
};
Derek Pollard
  • 6,953
  • 6
  • 39
  • 59
  • @JosephtheDreamer - `when` is this library: https://www.npmjs.com/package/when – Derek Pollard Feb 23 '16 at 17:00
  • @Down voter - why the down vote?? – Derek Pollard Feb 23 '16 at 17:00
  • Avoid the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572)! – Bergi Feb 23 '16 at 17:03
  • @Bergi - `doSomething` has to do other things before it can return the function – Derek Pollard Feb 23 '16 at 17:05
  • Would it still be considered an antipattern even then? @Bergi ? – Derek Pollard Feb 23 '16 at 17:10
  • @OliverQueen: Yes. Don't call a promise-returning function inside a `when.promise`. Of course, if the call to `doSomething` and the construction of the promise from some other (non-promised) async thing are two separate things, you may still put them both in the same function. E.g. `when.all([doSomething(), when.promise(…)])` or `when.promise(…).then(doSomething)` etc. – Bergi Feb 23 '16 at 17:22
  • @Bergi - I added an updated code to the question. I *think* I get what you're saying now. Mind taking a look at it and confirming? – Derek Pollard Feb 23 '16 at 17:31
  • @OliverQueen: Yes, that looks good, except you are missing the `return` to get back the result of the `then` callback from your function as a promise. Like in Joseph's answer. – Bergi Feb 23 '16 at 17:52

3 Answers3

3

The return of doAnotherThing appears to be a promise. You can simply chain a then and put your callback to utilize other. then also already returns a promise. You can return that instead.

// Do stuff
function doSomething(){
  return doAnotherThing(parameter).then(function(other){
    // Do more stuff
    return other
  });
}

// Usage
doSomething().then(function(other){
  // other
});
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • 1
    The "alternative" is the only alternative. The first snippet is an [antipattern](http://stackoverflow.com/q/23803743/1048572). – Bergi Feb 23 '16 at 17:02
  • What I guess I don't understand is that I need to wait for a process to return AFTER `doAnotherThing` occurs. How do I make the `then` function resolve and return FINAL data after it goes out and grabs data? – Derek Pollard Feb 23 '16 at 17:51
  • 1
    @OliverQueen: You can just `return` the final data from the `then` callback. That's [the magic of promises](http://stackoverflow.com/a/22562045/1048572) :-) – Bergi Feb 23 '16 at 17:54
0

Below is how to accomplish what you're trying to do with bluebird.

You can use Promise.resolve() and Promise.reject() within any function to return data in a Promise that can be used directly in your promise chain. Essentially, by returning with these methods wrapping your result data, you can make any function usable within a Promise chain.

var Promise = require('bluebird');

var doSomething = function(parameter) {
  // Call our Promise returning function
  return doAnotherThing()
    .then(function(value) {
      // Handle value returned by a successful doAnotherThing call
    })
    .catch(function(err) {
      // if doAnotherThing() had a Promise.reject() in it
      // then you would handle whatever is returned by it here
    });
}

function doAnotherThing(parameter) {
  var s = 'some data I got from the url';

  // Return s wrapped in a Promise
  return Promise.resolve(s);
}
peteb
  • 18,552
  • 9
  • 50
  • 62
-1

You can use the async module and its waterfall method to chain the functions together:

var async = require('async');

async.waterfall([
  function(parameter, callback) {
    doSomething(parameter, function(err, other) {
      if (err) throw err;
      callback(null, other); // callback with null error and `other` object
    });
  },
  function(other, callback) { // pass `other` into next function in chain
    doAnotherThing(other, function(err, result) {
      if (err) throw err;
      callback(null, result);
    })
  }
], function(err, result) {
  if (err) return next(err);
  res.send(result); // send the result when the chain completes
});

Makes it a little easier to wrap your head around the series of promises, in my opinion. See the documentation for explanation.

Bennett Adams
  • 1,808
  • 14
  • 17
  • No. You should use `then` to waterfall promises, not the `async` library which uses an entirely different syntactic convention. – Bergi Feb 23 '16 at 17:24