提问者:小点点

在for循环或数组方法中处理异步调用的不同方法是什么?


我一直在尝试创建一个这样的api,其中我尝试了不同的方法,比如使用map/filter/reduce这样的数组方法,在执行api调用之前,我会得到挂起的承诺或返回的结果。 所以我的怀疑是-->;

  • 如何获取所有页面的绘制匹配的总数(因此需要从所有页面添加Data.total)。
  • 如何更好地理解这种行为。

null

async function getNumDraws(year) {
    const goals = [...Array(11).keys()];
    let result = 0;

    console.log(`before loop ${new Date()}`);
    for(let goal of goals){
        console.log(`in loop before await ${new Date()}`);
        await require('https').get(`https://jsonmock.hackerrank.com/api/football_matches?year=${year}&team1goals=${goal}&team2goals=${goal}`,res=>{
            let data="";
            res.on('data', (chunk) => {
                data += chunk;
            });
            // The whole res has been received. Print out the result.
            res.on('end', () => {
                data=JSON.parse(data);
                console.log(result,data.total)
                result= result + data.total;
            });
        })
        console.log(`in loop after await ${new Date()}`);

    }
    console.log(`after loop ${new Date()}`);
    return result;
console.log(getNumDraws(2011));

}

null


共1个答案

匿名用户

https.get是一个回调函数,因此await无法工作。 你应该首先承诺它,就像他们在另一个问题中所做的那样;

const https = require("https");                                      // only require this once

const getJSONAsync = url => new Promise((resolve, reject) => {       // define a function getJSONAsync which returns a Promise that wraps the https.get call, getJSONAsync is awaitable
  let req = https.get(url, res => {                                  // make the https.get request
    if(res.statusCode < 200 || res.statusCode >= 300) {              // if the status code is an error one
      return reject(new Error('statusCode=' + res.statusCode));      // reject and skip the rest
    }

    let body = [];                                                   // otherwise accumulate..
    res.on('data', chunk => body.push(chunk));                       // ..the data
    res.on('end', () => {                                            // on end                               
      try {
        body = JSON.parse(Buffer.concat(body).toString());           // try to JSON.parse the data
      } catch(e) {
        reject(e);                                                   // reject if an error occurs
      }
      resolve(body);                                                 // resolve the parsed json object otherwise
    });
  });

  req.on("error", error => reject(error));                           // reject if the request fails too (if something went wrong before the request is sent for example)
});

async function getNumDraws(year) {
  let result = 0;

  for(let goal = 0; goal < 11; goal++) {
    let data = await getJSONAsync(`https://jsonmock.hackerrank.com/api/football_matches?year=${year}&team1goals=${goal}&team2goals=${goal}`);
    result += data.total;
  }

  return result;
}

注意:GetJsonAsync并不特定于GetNumDraus,如果需要,您可以在其他地方使用它,并且由于它返回了一个Promise,您可以像GetNumDrausdoes那样Await它,或者像这样将它与Then/Catch块一起使用:

getJSONAsync("url")
  .then(data => {
    // data is the parsed json returned by the request
  })
  .catch(error => {
    // the error message if something fails
  })