I'm new to promises and writing network code using requests and promises in NodeJS.
I would like to remove these nested promises and chain them instead, but I'm not sure how I'd go about it/whether it is the right way to go.
exports.viewFile = function(req, res) { var fileId = req.params.id; boxContentRequest('files/' + fileId + '/content', req.user.box.accessToken) .then(function(response) { boxViewerRequest('documents', {url: response.request.href}, 'POST') .then(function(response) { boxViewerRequest('sessions', {document_id: response.body.id}, 'POST') .then(function(response) { console.log(response); }); }); }); };
This is the request code:
var baseContentURL = 'https://api.box.com/2.0/'; var baseViewerURL = 'https://view-api.box.com/1/'; function boxContentRequest(url, accessToken) { return new Promise(function (resolve, reject) { var options = { url: baseContentURL + url, headers: { Authorization: 'Bearer ' + accessToken, } }; request(options, function (err, res) { if (err) { return reject(err); } else if (res.statusCode !== 200) { err = new Error("Unexpected status code: " + res.statusCode); err.res = res; return reject(err); } resolve(res); }); }); } function boxViewerRequest(url, body, method) { return new Promise(function (resolve, reject) { var options = { method: method, url: baseViewerURL + url, headers: { Authorization: 'Token ' + config.box.viewerApiKey }, json: body }; request(options, function (err, res, body) { if (err) { return reject(err); } else if (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 202) { err = new Error("Unexpected status code: " + res.statusCode); err.res = res; return reject(err); } resolve(res, body); }); }); }
Any insight would be appreciated.
In a promise nesting when you return a promise inside a then method, and if the returned promise is already resolved/rejected, it will immediately call the subsequent then/catch method, if not it will wait. If promised is not return, it will execute parallelly.
In order to break a promise honorably, you need to be sure to do the following: Acknowledge that you are breaking a promise. This isn't something you can mask or hide. Don't wait too long to communicate about this either.
You have to either return a promise or use a callback. Since you're already using promises internal to the function, you should just return a promise. You can return a promise from getColumn() and use . then() or await with that promise to get the value.
From every then
callback, you will need to return the new promise:
exports.viewFile = function(req, res) { var fileId = req.params.id; boxContentRequest('files/' + fileId + '/content', req.user.box.accessToken) .then(function(response) { return boxViewerRequest('documents', {url: response.request.href}, 'POST'); }) .then(function(response) { return boxViewerRequest('sessions', {document_id: response.body.id}, 'POST'); }) .then(function(response) { console.log(response); }); };
The promise that is returned by the .then()
call will then resolve with the value from the "inner" promise, so that you easily can chain them.
Generic pattern:
somePromise.then(function(r1) { return nextPromise.then(function(r2) { return anyValue; }); }) // resolves with anyValue || \||/ \/ somePromise.then(function(r1) { return nextPromise; }).then(function(r2) { return anyValue; }) // resolves with anyValue as well
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With