语句未按预期执行

时间:2019-06-28 07:50:15

标签: javascript node.js mongoose async-await

我正在编写代码以从api获取数据并将其保存在mongodb数据库中。我写的代码是:

     getSquadList: async (ctx) => {
var query = ctx.request.query;
var squadList = await getSquadsOfMatch(query.matchId);
if (squadList.length <= 1) {
  var response = await axios.get(
    `${strapi.config.currentEnvironment.getSquadListApi}?apikey=${strapi.config.currentEnvironment.cricApiKey}&unique_id=${query.matchId}`
  );

  squadList = response.data.squad;

  var match = await Match.findOne({
    unique_id: query.matchId
  });

  var team1Squad, team2Squad;

  await squadList.forEach(async squad => {
    if (squad.name === match['team-1']) {
      team1Squad = {
        name: match['team-1'],
        match_id: match['unique_id'],
        match: match['_id'],
      };

      await new Squad(team1Squad).save();
      console.log('1');
    } else if (squad.name === match['team-2']) {
      team2Squad = {
        name: match['team-2'],
        match_id: match['unique_id'],
        match: match['_id'],
      };

      await new Squad(team2Squad).save();
      console.log('2');
    }
  });

  squadList = await getSquadsOfMatch(query.matchId);
  console.log('3');
}
ctx.send(squadList);
      }

我已经使用console.log()查看执行顺序。我想要的顺序是1 2 3但实际输出是3 1 2 如何使程序最后执行这些行。         squadList =等待getSquadsOfMatch(query.matchId);           console.log('3');

2 个答案:

答案 0 :(得分:2)

如果我们模仿async的作用,则不能将forEach函数与forEach一起使用:

function forEach(arr, callback){
   for(let i=0;i<arr.length;i++){
        callback(arr[i], i, arr);
   }
}

如您所见,它不会await回调async

您可以创建自定义forEach,例如:

async function forEach(arr, callback){
   for(let i=0;i<arr.length;i++){
        await callback(arr[i], i, arr);
   }
}

或使用简单的for循环。

此外,您可以做的是将所有的Promise推送到一个数组中,然后调用Promise.all处理所有请求。

async (ctx) => {
    var query = ctx.request.query;
    var squadList = await getSquadsOfMatch(query.matchId);
    if (squadList.length <= 1) {
        var response = await axios.get(
            `${strapi.config.currentEnvironment.getSquadListApi}?apikey=${strapi.config.currentEnvironment.cricApiKey}&unique_id=${query.matchId}`
        );

        squadList = response.data.squad;

        var match = await Match.findOne({
            unique_id: query.matchId
        });

        var team1Squad, team2Squad;
        const promises = squadList.map(squad => {
            if (squad.name === match['team-1']) {
                team1Squad = {
                    name: match['team-1'],
                    match_id: match['unique_id'],
                    match: match['_id'],
                };
                console.log('1');
                return new Squad(team1Squad).save(); //returning the promise
            } else if (squad.name === match['team-2']) {
                team2Squad = {
                    name: match['team-2'],
                    match_id: match['unique_id'],
                    match: match['_id'],
                };
                console.log('2');
                return new Squad(team2Squad).save(); //returning the promise
            }
        });
        await Promise.all(promises); //making all the changes parallely

        squadList = await getSquadsOfMatch(query.matchId);
        console.log('3');
    }
    ctx.send(squadList);
}

注意::我写了一篇文章,介绍循环和异步函数,请随时查看https://medium.com/trappedpanda/loops-asynchronous-functions-and-returning-collective-results-in-node-js-b7566285fb74

答案 1 :(得分:0)

您可以创建一个必须首先执行的承诺数组,并在运行Promise.all之前使用getSquadsOfMatch等待它们解决:

getSquadList: async (ctx) => {
    var query = ctx.request.query;
    var squadList = await getSquadsOfMatch(query.matchId);
    if (squadList.length <= 1) {
      var response = await axios.get(
        `${strapi.config.currentEnvironment.getSquadListApi}?apikey=${strapi.config.currentEnvironment.cricApiKey}&unique_id=${query.matchId}`
      );

      squadList = response.data.squad;

      var match = await Match.findOne({
        unique_id: query.matchId
      });

      var team1Squad, team2Squad;

      const tasks = squadList.map(async squad => {
        if (squad.name === match['team-1']) {
          team1Squad = {
            name: match['team-1'],
            match_id: match['unique_id'],
            match: match['_id'],
          };

          await new Squad(team1Squad).save();
          console.log('1');
        } else if (squad.name === match['team-2']) {
          team2Squad = {
            name: match['team-2'],
            match_id: match['unique_id'],
            match: match['_id'],
          };

          await new Squad(team2Squad).save();
          console.log('2');
        }
      });

      await Promise.all(tasks)
      squadList = await getSquadsOfMatch(query.matchId);
      console.log('3');
    }
    ctx.send(squadList);
  }