You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能打印Pokemon数据但无法批量写入数据库,请求技术排查

问题:Pokemon数据种子脚本无法写入数据库,多次运行后完全失效

我可以通过console.log打印我的Pokemon数据,但无法将其导入(seed)到数据库中。最初运行种子文件时还能成功写入部分数据,但多次运行后就完全失效了。相关代码如下:

const Pokemon = require('../../models/Pokemon');
const faker = require('faker-br');
const axios = require('axios');

const seedPokemon = async function () {
    let PokemonArray = [];
    let i;
    for (i = 1; i < 50; i++) {
        axios.get(`https://pokeapi.co/api/v2/pokemon/${i}`).then(res => {
            PokemonArray.push({
                name: res.data.name,
                height: res.data.height,
                pokédex_index: res.data.id,
                pokémon_type: res.data.types[0].type.name,
                sex: faker.random.arrayElement(['male', 'female', 'non-binary']),
                photo: res.data.sprites.front_default
            })
        })
    }
    try {
        await Pokemon.sync({ force: true });
        await Pokemon.bulkCreate(PokemonArray);
    }
    catch (err) {
        console.log(err);
    }
};
module.exports = seedPokemon;

请问我哪里操作出错了?恳请协助解决。


问题原因与修复方案

核心错误:异步请求未等待完成

你的代码存在异步时序问题:

  • 循环中调用axios.get是异步请求,这些请求会在后台执行,但代码不会等待它们完成,就直接执行了后续的Pokemon.sync和bulkCreate。
  • 第一次运行偶尔写入部分数据,是因为个别请求刚好在bulkCreate执行前完成;多次运行后,网络或事件循环的差异导致所有请求都没来得及填充数组,PokemonArray为空,自然无法写入数据库。

修复后的代码

修改思路:收集所有API请求的Promise,用Promise.all等待所有请求完成后,再执行数据库操作,同时用async/await简化异步逻辑:

const Pokemon = require('../../models/Pokemon');
const faker = require('faker-br');
const axios = require('axios');

const seedPokemon = async function () {
    try {
        // 收集所有API请求的Promise
        const pokemonPromises = [];
        for (let i = 1; i < 50; i++) {
            pokemonPromises.push(
                axios.get(`https://pokeapi.co/api/v2/pokemon/${i}`).then(res => {
                    return {
                        name: res.data.name,
                        height: res.data.height,
                        pokédex_index: res.data.id,
                        pokémon_type: res.data.types[0].type.name,
                        sex: faker.random.arrayElement(['male', 'female', 'non-binary']),
                        photo: res.data.sprites.front_default
                    };
                })
            );
        }

        // 等待所有请求完成,获取完整的Pokemon数据数组
        const PokemonArray = await Promise.all(pokemonPromises);

        // 同步数据库并批量插入数据
        await Pokemon.sync({ force: true });
        await Pokemon.bulkCreate(PokemonArray);
        
        console.log('Pokemon数据种子导入成功!');
    } catch (err) {
        console.error('种子导入失败:', err);
    }
};

module.exports = seedPokemon;

额外优化建议

  1. 单个请求错误处理:给每个axios请求单独添加catch,避免一个请求失败导致整个批量操作终止:
pokemonPromises.push(
    axios.get(`https://pokeapi.co/api/v2/pokemon/${i}`)
        .then(res => {
            return { /* 数据结构 */ };
        })
        .catch(err => {
            console.error(`获取第${i}个Pokemon数据失败:`, err);
            return null; // 返回null,后续过滤掉无效数据
        })
);
// 过滤掉请求失败的空数据
const PokemonArray = (await Promise.all(pokemonPromises)).filter(item => item !== null);
  1. 控制并发请求数:如果请求数量很大,一次性发起太多请求可能触发API限流,可以分批处理或用第三方库(如p-limit)控制并发数。

内容的提问来源于stack exchange,提问作者fipdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:51:33