0

I have a requirement where we need to write a node module using promises. So there would be 3 different promises. Result should be sent back only when all three of them resolve. I have written some code. Currently the result comes as undefined. Let me know what can I add to fix this.

This is the node module code -

var exports = module.exports = {};

exports.getData = function() {
    var Q = require('q');

    var result = 0;

    // Promise 1
    var deferred = Q.defer();

    var promise1 = Q.fcall(function() {
      setTimeout( function(){console.log('hi');deferred.resolve(9);}, 1000 );
      return deferred.promise;
    });


    promise1.then(function(contents) {
        result = result + contents;
      console.log(contents);
    });

    // promise 2

    var deferred2 = Q.defer();

    var promise2 = Q.fcall(function() {
      setTimeout( function(){console.log('hi');deferred2.resolve(10);}, 1000 );
      return deferred2.promise;
    });


    promise2.then(function(contents) {
        result = result + contents;
      console.log(contents);
    });

    // promise3

    var deferred3 = Q.defer();

    var promise3 = Q.fcall(function() {
      setTimeout( function(){console.log('hi');deferred3.resolve(11);}, 1000 );
      return deferred3.promise;
    });


    promise3.then(function(contents) {
        result = result + contents;
      console.log(contents);
    });

};

This is the invoking code -

var x = require('./example5.js');

var result = x.getData();

console.log(' Result is ' + result);

So I need to figure out a way to hold on to the execution of the node module until all the promises are resolved.

Currently the output is -

Result is undefined

P.S I am a newbie to node.js. So if this is something very obvious, please excuse me!

I think the question was flagged as duplicate. However in the other question, I could not find solution to return the result back. It still returns the promise.

user3276247
  • 1,046
  • 2
  • 9
  • 24
  • If the promises are indepentent of each other, Promise.all should do the trick. Otherwise research [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) to deal with the nesting hell that you might run into when having too much then-ables. – k0pernikus May 23 '17 at 14:49
  • Will await work with q promise library ? – user3276247 May 23 '17 at 15:02
  • I checked the other question. It does not mention how to return the final result back. The requirement is not to return the promise back. – user3276247 May 23 '17 at 15:03
  • @user3276247 It does though. It's an asynchronous operation so you need to handle getting the final result via the `.then` function. – Mike Cluck May 23 '17 at 15:24
  • @MikeC, Actually the requirement is that we host the service and external clients can access this service as a REST service. Now to this client, we need to return data and not the promise. So I need to figure out a way to return the final data back. – user3276247 May 23 '17 at 16:20
  • @user3276247 They have to respond to the Promise. Either using `then` or `await`. There is literally no other way. The Promise is an asynchronous process carrying the data you need. You absolutely, positively cannot access asynchronous data from a synchronous process. It's like asking someone to make you a burger then running by the grill with your arm out. The burger is not going to be ready. You have to wait for them to tell you it's done. – Mike Cluck May 23 '17 at 16:27
  • @user3276247 If it's a REST service and you're writing the server side of it, don't send a response back to the user until you've gotten your data back. If you're writing the client-side which is consuming the service, they have to wait for a callback to their (presumably) AJAX call like normal. – Mike Cluck May 23 '17 at 16:29
  • @MikeC The idea is to write the server code in node.js. That is why we are trying to explore as to how not to send a response back to the user until the data is available from the services. – user3276247 May 23 '17 at 16:48
  • @user3276247 Then you've taken the right step with writing it with promises. If you're using express then just have to do, if I remember correctly, `promise.then(data => res.send(data))` give or take some for manipulating your data. – Mike Cluck May 23 '17 at 17:48

1 Answers1

2

You can use Promise.all(), to get "a single Promise that resolves when all of the promises in the iterable argument have resolved, or rejects with the reason of the first promise that rejects".

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
}); 

Promise.all([p1, p2, p3]).then(values => { 
  console.log(values); // [3, 1337, "foo"] 
});
shabs
  • 718
  • 3
  • 10