等待嵌套的promises以最内层

时间:2018-06-05 00:20:20

标签: javascript node.js callback

在最外面的 for 循环遍历一个数组,这个数组更具体地说是一个对象列表,其中每个对象都包含一个数组,其中包含我需要使用的代码,以便获得由外部API(为了简单起见,我使用的是模型对象):

  

data = [{resultOfRequest,[code1,code2,code3]},{resultOfRequest,   [code4,code5,code6]},...}

我需要遍历数据数组,每个codeX发出一个请求并将结果存储在resultOfRequest上。

在顺序范例中它将是这样的:

for all items in data as work: 
     for all items in work as codeArray:
            for all codes in codeArray as code:
                   work.result = request(to-api, code) //waiting here for termination

我开始使用javascript几天了,我读过它意味着非阻塞,但是对于这个特定的任务,我必须让它同步并等到所有对象都被检查。

我的尝试涉及承诺,看起来像这样:

//here the map iterates over the data array
// work = {resultOfRequest, [code1,code2,code3] }

  Promise.all(data.map((work, index) => {
             orclass.elserec(work, 0).then((results) => {
                    console.log(results);
             });
  }))
  .then(results => {
      console.log("finished")
  });

因为我需要在它到达索引3时结束递归调用,所以我必须在回调时执行此操作:

 // here i try to iterate through the codeX arrays, and making requests 
//(where work =  {resultOfRequest,  [code1, code2, code3]})

  elserec: function(work, i){

    return request('api-url-code= work.array[i]', function(error, response, body) {
        result = JSON.stringify(JSON.parse(body));
        if (!error && response.statusCode == 200 && i !== 3) {
            console.log(result);
            work.resultOfRequest.push(result);
            return orclass.elserec(work, i+1);
        } else {            
            return result;
        }
    });
  }

它停留在数据[0]的第3个请求。

我更愿意只使用回调来解决这个问题,只是为了掌握它们的工作方式,因为我从未使用过javascript,宁愿更喜欢先使用promises之前的东西来学习(这个更具体上下文,简单异步上下文中的回调并不是什么特别的我知道)!

1 个答案:

答案 0 :(得分:0)

我找到了一种方法来完成这项工作。

递归调用并不是一个好主意,所以我将一个函数(带有请求承诺)映射到带有代码的数组([code1,code2,code3]),最后我得到[elrec(code1), elrec(code2),elrec(code3)]。然后我用promise上的promises调用promise.all。它有效:

Promise.all(data.map((works, index) => {
    return Promise.all(works.map((work, index) => {
             var promises = work.scopus.map(function(obj){
                return orclass.elrec(work,obj).then(function(results){
                   console.log("working!!!!!!");
                })
              })
             return Promise.all(promises);
    }))
})).then(function(){ //all api calls are done, proceed here})

elrec功能:

elrec: function(work, code) {
    return request('https://api.*****' + code + '*****',
        function(error, response, body) {

            if (!error && response.statusCode == 200) {
                result = JSON.stringify(JSON.parse(body));
                work.elsev.push(result);
            } else if (response.statusCode == 404) {
                work.elsev.push("failed req");
            }
        });
}

正如我想的那样,我可以等待所有承诺成为"满足" (对所有代码执行所有API请求)并在此之后采取措施。