【问题标题】:Removing nested promises移除嵌套的 Promise
【发布时间】:2014-03-26 18:56:56
【问题描述】:

我不熟悉 Promise 和使用 NodeJS 中的请求和 Promise 编写网络代码。

我想删除这些嵌套的 Promise 并将它们链接起来,但我不确定我将如何去做/这是否是正确的方法。

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);
                    });
            });
    });
};

这是请求代码:

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);
      });
    });
}

任何见解将不胜感激。

【问题讨论】:

  • 您可能对Request-Promise 感兴趣。使用这个库,您可以节省一些代码来将请求包装到一个承诺中。

标签: javascript node.js request promise


【解决方案1】:

从每个then 回调中,您需要返回新的承诺:

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);
      });
};

.then() 调用返回的 Promise 将使用“内部”Promise 中的值解析,以便您轻松链接它们。

通用模式:

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

【讨论】:

    【解决方案2】:

    Promise.prototype.then 旨在返回另一个承诺,以便您可以将它们链接起来。

    传递给.then() 的处理函数可以返回一个正常值,如数字、字符串或对象,并且这个值将被传递给.then() 的下一个处理函数。 p>

    一种选择是让boxViewerRequestSync 成为一个返回response 对象的同步函数:

    boxContentRequest('files/' + fileId + '/content', req.user.box.accessToken)
        .then(function(response) {
            return boxViewerRequestSync('documents', {url: response.request.href}, 'POST')
        })
        .then(function(response) { // this `response` is returned by `boxViewerRequestSync`
            return boxViewerRequestSync('sessions', {document_id: response.body.id}, 'POST')
        })
        .then(function(response) {
            console.log(response);
        })
    

    当然你的boxViewerRequest 是异步的,而是返回一个promise。在这种情况下,传递给.then() 的处理函数也可以返回completely unrelated Promise。这个新的承诺是同步执行的,一旦它被解析/拒绝,它的结果就会被传递给下一个处理程序。

    boxContentRequest('files/' + fileId + '/content', req.user.box.accessToken)
        .then(function(response) {
            return boxViewerRequest('documents', {url: response.request.href}, 'POST')
        })
        .then(function(response) { // this `response` is the result of resolving the promise returned by `boxViewerRequest`
            return boxViewerRequest('sessions', {document_id: response.body.id}, 'POST')
        })
        .then(function(response) {
            console.log(response);
        })
    

    跟踪所有的 Promise 令人困惑,但底线是:Promise.prototype.then总是 返回一个 Promise 对象,但处理函数 传递 给 @ 987654333@ 可以返回任何东西,甚至是未定义的,甚至是另一个 Promise。然后那个值,或者解析的 Promise 的值,被传递给下一个处理函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-02
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多