javascript - 异步等待不等待对象填充 axios.get

标签 javascript node.js async-await axios

我有一个名为 move_dict 的对象并且正在使用方法get_learned_by_pokemon()填补它。在 getPokes()我调用 get_learned_by_pokemon()并期待 move_dict被填满。然而它是空的。

function move(){
    let move_dict = {}
    let db_data = JSON.parse(fs.readFileSync('pokes.json', 'utf8'));
    async function get_learned_by_pokemon(curr_move, move_dict, current_poke){
        response = await axios.get('https://pokeapi.co/api/v2/move/'.concat(curr_move))

        let learned_by_pokemons = []
        for (let k = 0; k < response.data.learned_by_pokemon.length; k++){
            learned_by_pokemons.push(response.data.learned_by_pokemon[k].name)
        }
        // pass
        if (learned_by_pokemons.includes(current_poke)){move_dict[current_poke].pass.push(curr_move)}
        // fail
        else{move_dict[current_poke].fail.push(curr_move)}

    }
    function getPokes(){
        //iterate through all pokemon
        for (let i = 0; i < db_data.length; i++){
            let current_poke = db_data[i].name
            let moves = db_data[i].moves
            move_dict[current_poke] = {pass: [], fail: []}
            //iterate through all moves of pokemon
            for (let j = 0; j < moves.length; j++){
                let curr_move = moves[j]
                //get data on current move
                get_learned_by_pokemon(curr_move, move_dict, current_poke)
            }
        }
    }

    getPokes()
}
我还在 Axios.get() 之前使用了 await
.我想知道为什么 move_dict 没有填充,我想在不使用 setTimeout() 的情况下克服这个问题。

最佳答案

看起来 OP 以描述口袋妖怪的 json 文件开头。从代码来看,该文件至少包含以下内容......

[
  { name: 'nameA', moves: [ 1, 2, 3, ... ] },
  { name: 'nameB', moves: [ 3, 4, 5, ... ] },
  ...
]
看起来有一个 api 端点进行移动(“id 或名称”)并返回除其他外,已“学习”该移动的 pokemon 列表。
看起来OP旨在制作这样的字典......
{
  nameA: { pass: [1, 2, ...], fail: [3, 4, ...] },
  nameB: { pass: [3, 4, ...], fail: [4, 5, ...] },
 ...
}
...在输入文件中找到的通过和失败数组移动的位置根据 api 移动或未学习移动。
由于我们不想重复调用 api,并且由于输入文件中可能存在冗余 Action ,因此值得创建一个中间结构,将输入中的独特 Action 与学习它们的口袋妖怪相关联,就像这样。 ..
{ // key is a move id or name, value is an array of pokemon names
  1 : [ 'nameA', 'nameB', ... ],
  2 : [ 'nameC', 'nameD', ... ],
  ...
}
所以这就是我在代码中描述这个想法的方式(未编译或测试)......
async function get_learned_by_pokemon(move){
  const response = await axios.get(`https://pokeapi.co/api/v2/move/${move}`);
  return response.data.learned_by_pokemon.map(p => p.name);
}

async function move() {
  let db_data = JSON.parse(fs.readFileSync('pokes.json', 'utf8'));
  let allMoves = db_data.flat_map(p => p.moves);
  let uniqueMoves = [...new Set(allMoves)];

  // map move ids to pokemons who learned the moves  { moveId: [ 'pokeA', 'pokeB' ...], ...}
  let learnedBy = {}
  for (let move in uniqueMoves) {
    learnedBy[move] = await get_learned_by_pokemon(move);
  }

  // map pokemon names to a pair of arrays indicating if they have learned their moves (pass) or not (fail)
  let move_dict = db_data.reduce((acc, p) => {
    let name = p.name;
    let pass = p.moves.filter(move => learnedBy[move].includes(name));
    let fail = p.moves.filter(move => !learnedBy[move].includes(name));
    acc[name] = { pass, fail };
    return acc;
  }, {});

  return move_dict;
}

关于javascript - 异步等待不等待对象填充 axios.get,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72298501/

相关文章:

javascript - 悬停时预加载页面并单击链接

javascript - jQuery 为作用域设置祖先元素

java - Three.js:如何将场景转换为 MPG4 视频?

javascript - 在 promise 中循环直到另一个 promise 结束

c# - 下面的普通 lambda 和异步 lambda 有什么区别吗?

javascript - 日期或文本类型的 HTML 输入在 SVGforeignObject 中不起作用

javascript - Node JS - 文件生成器架构

node.js - 非socket.io 进程的示例是什么?

c# - 这是获得运行异步任务所需时间的最佳方式吗?

javascript - 如何调用异步函数?