Reputation: 2085
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
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