我很擅长承诺并使用NodeJS中的请求和承诺编写网络代码。
我想删除这些嵌套的promises并将它们链接起来,但我不确定我是怎么做的/它是否是正确的方法。
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);
});
});
}
任何见解都将受到赞赏。
答案 0 :(得分:25)
从每个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()
调用返回的承诺将使用“内部”承诺中的值解析,以便您可以轻松链接它们。
通用模式:
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
答案 1 :(得分:1)
Promise.prototype.then
旨在返回另一个承诺,以便您可以链接它们。
传递给.then()
的处理函数可以返回正常值,就像数字或字符串或对象一样,这个值将被传递给{{1}的下一个处理程序}。
一个选项是让.then()
成为返回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);
})
是异步的,而是返回一个promise。在这种情况下,传递给boxViewerRequest
的处理函数也可以返回completely unrelated Promise
。这个新的promise是同步执行的,一旦解析/拒绝,它的结果就会被传递给下一个处理程序。
.then()
跟踪所有承诺令人困惑,但最重要的是: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。然后将该值或已解析的Promise的值传递给下一个处理函数。