我试图在这里概述How do I access previous promise results in a .then() chain?
中获取承诺中的先前结果我设法使用2个承诺来处理此问题,但是当我添加第3个向API发出POST请求时,承诺结果是我的发布请求,而不是来自该帖子请求的响应。
基本上我的应用程序的流程是。我将一个项目插入数据库。使用该insertId然后我将多个项目插入到数据库中,这些项目是“孩子们”。第一个insertId。但我还需要将这些值发送到API。然后,此API将返回另一个ID,我将最终与我之前的insertID相关联。代码大致如下(为了简洁起见,我已经删除了一些其他逻辑和错误处理)。
let name = req.body.name;
let value = req.body.values;
let obj = {name:name};
let entries = [];
let a = db.items.insertItem(name);
let b = a.then((data) => {
let insertId = data.insertId;
let promises = [];
values.forEach((val) => {
entries.push({value:val)})
promises.push( db.values.insertValuesForItem(insertId,val));
})
obj.entries = entries;
return promises;
})
let c = b.then((data) => {
return request.post(constants.devUrl,
{
headers:{
'Authorization': 'bearer ' + constants.developerToken,
'content-type': 'application/json'
},
json:obj
});
});
Promise.all([a,b,c]).then(([resa,resb,resc]) => {
//resc here contains the post request info e.g the post data and headers
// what I really want from resc is the response from my post request
res.redirect(200,'/items/' + resa.insertId);
})
正如我之前提到的,在resc中我实际上需要来自API请求的响应,而不是请求本身的详细信息。我是如何实现这一目标的?
答案 0 :(得分:2)
现在问题重新开始了,重申我在评论中所说的话:
您的代码中存在两个问题:
错误地链接承诺:
let b = a.then((data) => {
let insertId = data.insertId;
let promises = [];
values.forEach((val) => {
entries.push({value:val)})
promises.push( db.values.insertValuesForItem(insertId,val));
})
obj.entries = entries;
return promises; // this variable is accessed later as `data`, but
// never actually used => it's pointless
})
由于您返回promises
,您实际上正在返回Promise
,只有在履行时才会返回您的承诺数组。这意味着:
b
成功回调中,您将获得data
(promises
数组),但不会对其执行任何操作。 Promise.all([a,b,c]).then(([resa,resb,resc])
内,resb
是承诺数组,而不是db
执行结果。我理解您正在尝试同步执行,但这不是正确的方法。
错误地期望request.post
返回承诺:
let c = b.then((data) => {
return request.post(constants.devUrl,
{
headers:{
'Authorization': 'bearer ' + constants.developerToken,
'content-type': 'application/json'
},
json:obj
});
});
正如您在评论中提到的,您正在使用this requests
lib。因此,在这种情况下,c
确实是Promise
,但其返回值不是您期望的httpResponse
。
如果你想使用requests
以便它返回promises,你需要使用these variances of the requests lib中的一个返回promises。
但是,如果您不想更改lib,则可以通过传递post
方法的回调函数来同步执行。例如
var gotResponseCallBack = function(err, httpResponse, body){
return httpResponse;
}
request.post(constants.devUrl,
{
headers:{
'Authorization': 'bearer ' + constants.developerToken,
'content-type': 'application/json'
},
json:obj
}, gotResponseCallBack);