kayasa
kayasa

Reputation: 2085

Return value back from Promise to Promise.All

I am creating a function in Node js Express, that would be called by clients to download content.

The content needs to be downloaded from disparate sources and response needs to be send back only when all downloads have completed (content downloaded by node is zipped and send back to the calling client). So, all the download functions are wrapped in Promise.all(download1(), download2(), download3())

One of the download functions not only downloads content but it also generates a json and sends it back to the main function. The main function sets it as a response header.

The API function called by client looks like this

function downloadAll(request, response) {
    // Download content only after folders are created
    return createDirPromise.then(function (result) { 
       var statusJson = ... // somehow get the status json from download1() so that it can be send to the client 
       return Promise.all([download1(contentsJson), download2(contentsJson), download3(contentsJson)]);
    })
    .then(function (result) {
        return new Promise(function (resolve, reject) {             
        // Create zip. Here is the zip creation logic.  
        // Once zip is created, send it to client as a buffer
            zipdir(zipFolderPath, function (err, buffer) { 
            if (err) { 
               console.log('Error while zipping!!! '+JSON.stringify(err));
                    return reject({ data: null, resp_status_code: 500, resp_status_message: JSON.stringify(err)});
            }                        }
            console.log('Zipping successful');
            return resolve(
               { 
                 data: buffer, 
                 resp_status_code: 200, 
                 resp_status_message: "Zip succeeded", 
                 headers: statusJson
               });
        })
     })  
    .catch(function (error) { 
        return { 
            data: 'Error in any of above ' + error, 
            resp_status_code: 500, 
            resp_status_message: 'Error while zipping'
        }
}

This is how download1 function looks like

function download1(contentsJson) {
    return new Promise(function(resolve, reject) {
            //set the status json here
            var statusJson = { "key1": "value1", "key2": "value2"};
            //do the download stuff here and return the statusJson
            console.log('Downloading complete, return the status so that it can be send to the client'); 
            resolve(statusJson);
       }

I know how to send the headers back to the client. My challenge is how to get the statusJson in the downloadAll function. download1 function is called from within Promise.all(). As soon as download1, download2 and donwload3 complete '.then' is executed. I am not able to find a way to get the data (statusJson) returned by donwload1 inside downloadAll.

Upvotes: 1

Views: 818

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074335

I am not able to find a way to get the data (statusJson) returned by donwload1 inside downloadAll.

It's the first entry in the array that you receive as result in your then callback on the Promise.all():

function downloadAll(request, response) {
    return createDirPromise.then(function (result) { 
       return Promise.all([download1(contentsJson), download2(contentsJson), download3(contentsJson)]);
    })
    .then(function (result) 
        // **** Here, the result of download1 is result[0]
        var statusJson = result[0];

Promise.all gathers together the promise results and returns them in an array in the order you gave it the promises.

(Side note: I think you're missing () after createDirPromise.)

Example:

// (Requires Promise support in your browser)
"use strict";
var createDirPromise = createPromiseFunction("createDirPromise");
var download1 = createPromiseFunction("download1");
var download2 = createPromiseFunction("download2");
var download3 = createPromiseFunction("download3");

function downloadAll(request, response) {
  return createDirPromise().then(function(result) {
      return Promise.all([download1(/*contentsJson*/), download2(/*contentsJson*/), download3(/*contentsJson*/)]);
    })
    .then(function(result) {
      // **** Here, the result of download1 is result[0]
      var statusJson = result[0];
      console.log("statusJson = '" + statusJson + "'");
    });
}
downloadAll();

function createPromiseFunction(name) {
  return function() {
    return new Promise(function(resolve) {
      setTimeout(function() {
        console.log("resolving " + name);
        resolve("result of " + name);
      }, Math.random() * 50);
    });
  };
}

Upvotes: 1

Related Questions