【问题标题】:Statements are not executing as expected [duplicate]语句未按预期执行[重复]
【发布时间】:2019-11-10 04:17:28
【问题描述】:

我正在编写代码以从 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 我怎样才能让程序在最后执行这些行。 小队列表 = 等待 getSquadsOfMatch(query.matchId); console.log('3');

【问题讨论】:

  • 你不能 await.forEach,因为 .forEach 调用本身不是异步的。
  • 你可以在 medium 上查看this article

标签: javascript node.js mongoose async-await


【解决方案1】:

如果我们模仿forEach 的作用,您不能将async 函数与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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 这不起作用,因为您没有从map返回任何承诺
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多