简体   繁体   English

链接承诺与以前的结果

[英]Chaining promises with previous results

I'm trying to get my head around accessing previous results in promises as outlined here How do I access previous promise results in a .then() chain? 我正在努力使自己的头脑访问此处所述的Promise中的先前结果如何在.then()链中访问先前的Promise结果?

I've managed to get this working with 2 promises, but when I add a 3rd that makes a POST request to an API the promise result is my post request and not the response from that post request. 我设法使它与2个诺言一起工作,但是当我添加一个向API发出POST请求的第3个诺言时,诺言结果是我的发布请求,而不是该发布请求的响应。

Basically the flow of my app is. 基本上我的应用程序流程是。 I insert an item into a DB. 我将一个项目插入数据库。 Using that insertId I then insert multiple more items into a database that are 'children' of the first insertId. 然后,使用该insertId,我将多个作为第一个insertId的“子级”的项目插入数据库。 But I also need to then send these values to an API. 但是我还需要将这些值发送到API。 This API will then return me another ID which I will ultimately associate with my own previous insertID. 然后,此API将向我返回另一个ID,该ID将最终与我自己的先前insertID相关联。 The code is roughly as follows (I've removed some other logic and error handling for the sake of brevity). 该代码大致如下(为简洁起见,我删除了一些其他逻辑和错误处理)。

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

As I mentioned previously, in resc I actually need the response from the API request, not details of the request itself. 如前所述,在resc中,我实际上需要来自API请求的响应,而不是请求本身的详细信息。 Any ideas how I achieve that? 有什么想法可以实现吗?

Now that the question was reopened, reiterating what I said in the comments: 现在,问题已经重新开始,重申了我在评论中所说的内容:

You have two problems in your code: 您的代码中有两个问题:

  1. Incorrectly chaining the promises: 错误地链接了诺言:

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

    Since you return promises , you are in fact returning a Promise that, only when fulfilled , will return your array of promises. 由于您返回了promises ,因此您实际上是在返回一个Promise只有兑现Promise可以返回诺言。 This means that: 这意味着:

    1. inside the b success callback, you are getting data (which is promises array) but not doing anything with it. b成功回调中,您正在获取data (这是promises数组),但不对其执行任何操作。
    2. inside Promise.all([a,b,c]).then(([resa,resb,resc]) , resb is the array of promises, not the results of the db execution. Promise.all([a,b,c]).then(([resa,resb,resc])resbresb的数组,而不是db执行的结果。

    I understand you're trying to synchronize the execution, but it's not the right approach. 我了解您正在尝试同步执行,但这不是正确的方法。

  2. Incorrectly expecting request.post to return a promise: 错误地期望request.post返回承诺:

     let c = b.then((data) => { return request.post(constants.devUrl, { headers:{ 'Authorization': 'bearer ' + constants.developerToken, 'content-type': 'application/json' }, json:obj }); }); 

    As you mentioned in the comments, you're using this requests lib . 如评论中所述,您正在使用requests lib As such, c in this case, is indeed a Promise , but its return value is not httpResponse as you expect. 因此,在这种情况下, c确实是Promise ,但是其返回值不是您期望的httpResponse

    • If you want to work with requests so that it returns promises, you need to use one of these variances of the requests lib , which are returning promises. 如果要处理requests以使其返回承诺,则需要使用请求lib这些变体之一 ,它们正在返回承诺。

    • If, however, you don't want to change the lib, you can synchornize the execution by also passing a callback function for the post method. 但是,如果您不想更改库,则可以通过传递post方法的回调函数来同步执行。 For example 例如

       var gotResponseCallBack = function(err, httpResponse, body){ return httpResponse; } request.post(constants.devUrl, { headers:{ 'Authorization': 'bearer ' + constants.developerToken, 'content-type': 'application/json' }, json:obj }, gotResponseCallBack); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM