首页 > 解决方案 > wait for nested promises to end with multiple requests on innermost

问题描述

On the outmost for loop iterates over an array, this array is more specifically a list of objects where each contains an array with codes that i need to use in order to reach some information provided by an external API (For the sake of simplicity i am using mockup objects):

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

I need to traverse the data array, making one request per codeX and storing the result on resultOfRequest.

on a sequential paradigm it would be something like this:

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

I started with javascript a couple of days, and i've read it's meant to be non-blocking, but for this specific task i have to make it synchronous and wait until all objects have been inspected.

My attempt involves promises and looks like this:

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

And as i need to end the recursive calls when it hits the index 3, i must do this at the callback:

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

It gets stuck at the 3rd request of the data[0] .

I would prefer to use only callbacks for this one, just to get a grip of how they work as i never used javascript , would rather prefer to use what came before promises first, to learn (In this more specific context, callbacks in a simple asynchronous context are not anything special i know)!

标签: javascriptnode.jscallback

解决方案


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

递归调用不是一个好主意,所以我将一个函数(带有请求承诺)映射到带有代码([code1,code2,code3])的数组,我最终得到 [elrec(code1),elrec(code2) ,elrec(code3)] 。之后我用数组上的 promise 调用 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 请求都已完成),然后再采取行动。


推荐阅读