链接承诺与以前的结果

时间:2018-01-26 07:19:20

标签: javascript promise

我试图在这里概述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请求的响应,而不是请求本身的详细信息。我是如何实现这一目标的?

1 个答案:

答案 0 :(得分:2)

现在问题重新开始了,重申我在评论中所说的话:

您的代码中存在两个问题:

  1. 错误地链接承诺:

    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只有在履行时才会返回您的承诺数组。这意味着:

    1. b成功回调中,您将获得datapromises数组),但不会对其执行任何操作。
    2. Promise.all([a,b,c]).then(([resa,resb,resc])内,resb是承诺数组,而不是db执行结果。
    3. 我理解您正在尝试同步执行,但这不是正确的方法。

    4. 错误地期望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);