Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing nested promises

Tags:

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.

like image 745
Tarrence Avatar asked Feb 24 '14 21:02

Tarrence


People also ask

How do you handle nested promises?

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.

How do you remove a promise?

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.

How do I return a nested promise?

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.


1 Answers

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 
like image 185
Bergi Avatar answered Sep 22 '22 01:09

Bergi