简体   繁体   中英

Wait for API to return its response before executing the next iteration in nodejs

I am new to nodejs. I have an array of string that consists of around 30000+ values, which has the below format

tickerArray = ["A","AA","AAA", ..........., "C"]

I want to loop through these and need to sent each value to an external polygon.io API. But the Polygo.io free plan only allows 5 API Call per minute. Below is my code.

await tickerArray.reduce((key:any, tickerSymbol:any) =>
    key.then(async () => await stockTickeDetails.runTask(tickerSymbol)),
    starterPromise
    );
}).catch(function (error: any) {
    console.log("Error:" + error);
   });

My runTask function is below :

public  runTask(tickerSymbol:any) {
 return  axios.get('https://api.polygon.io/v1/meta/symbols/' + tickerSymbol + '/company?apiKey=' + process.env.API_KEY).then(
   function (response: any) {
        console.log("Logo : " + response.data.logo + 'TICKER :' + tickerSymbol);
        let logo = response.data.logo;
        let updateLogo =  stockTickers.updateOne({ ticker: tickerSymbol }, { $set: { "logo": logo } })
      }).catch(function (error: any) {
        console.log("Error from symbol service file : " + error);
      });

}

Here what I need is, if I pass the 0th index value ie, "A" to runTask method, it should process the API and should return the result and from the result I need to update the database collection accordingly. Then should go back to the 1code and need to fetch the 1st index value ie "AA" and repeat the process.

Here after executing 2 APIs I am getting the following error

Request failed with status code 429. You've exceeded the maximum requests per minute.

I guess this is because it is not waiting till the request to get processed with each value. How can I resolve it by adding a set time out which delays 5 API call per minute.

You can easily achieve this using Promise pattern, here is your solution:

var tickerArray = ["A","AA","AAA", ..........., "C"]
let requests = tickerArray.map(tickerSymbol => {
   //generate a promise for each API call
   return new Promise((resolve, reject) => {
      request({
         uri: https://api.polygon.io/v1/meta/symbols/' + tickerSymbol + '/company?apiKey=' + process.env.API_KEY,
         method: 'GET'
      },
      (err, res, body) => {
      if (err) { reject(err) }
      //call to resolve method which is passed to the caller                             
      //method passed to the promise
      resolve( { response : body, request: tickerSymbol })
      })
   })
})

Promise.all(requests).then((objArray) => { 
//this is expected when all the promises have been resolved/rejected.
    objArray.forEach(obj => {
        if (obj) {
            console.log("Logo : " + obj.response.data.logo + 'TICKER :' + obj.request);
            let logo = obj.response.data.logo;
            let updateLogo =  stockTickers.updateOne({ ticker: obj.request }, { $set: { "logo": logo } })
        }
    })
}).catch(error => console.log("Error from symbol service file : " + error);)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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