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

Apollo Client循环中查询未等待完成问题排查求助

问题分析及修复方案

1. 冗余的Promise封装(核心问题)

Apollo Client的client.query本身就返回Promise,没必要手动包裹一层新的Promise。这种冗余封装不仅多余,还会导致错误无法被捕获——如果查询出现网络错误、GraphQL语法错误等,自定义Promise永远不会resolve或reject,可能引发代码卡死或异常行为。

2. 重复的Locale ID导致缓存触发

你的locales数组里所有项的id都是'fi',三次查询完全相同,Apollo Client默认的缓存策略会直接返回缓存结果,看起来像是“循环没等待”,实际是缓存加速了重复请求。这大概率是笔误,需要修正为对应语言的真实ID(比如瑞典语'sv'、英语'en')。

3. await与.then混合的冗余写法

fetchAllTranslations中同时使用await和.then,语法虽合法但可读性差,建议统一用await风格简化代码。


修复后的完整代码

import pkg from '@apollo/client'
import * as fs from 'fs'

const { ApolloClient, InMemoryCache, gql } = pkg

const cmsUrl = 'HIDDEN'

const client = new ApolloClient({
  uri: cmsUrl,
  cache: new InMemoryCache(),
})

// 修正locale的id为正确值
const locales = [
  {
    name: 'finnish',
    id: 'fi',
  },
  {
    name: 'swedish',
    id: 'sv',
  },
  {
    name: 'english',
    id: 'en',
  },
]

// 去掉冗余Promise封装,直接返回query的Promise链
const fetchTranslations = async (locale) => {
  const result = await client.query({
    query: gql`
      query GetTranslations($localeId: String!) {
        translations(first: 10000, locales: $localeId) {
          translation
          translationId
          locale
        }
      }
    `,
    // 使用GraphQL变量注入参数,避免字符串拼接风险
    variables: {
      localeId: locale.id
    }
  })

  return result.data.translations.reduce((acc, curr) => {
    acc[curr.translationId] = curr.translation
    return acc
  }, {})
}

const fetchAllTranslations = async () => {
  try {
    for (const locale of locales) {
      console.log(`Fetching translations for ${locale.name}...`)
      // 统一用await替代.then,简化逻辑
      const response = await fetchTranslations(locale)
      console.log(response)
      // 合并两次文件写入操作,减少IO开销
      fs.writeFileSync(`src/translation/${locale.id}.json`, JSON.stringify(response))
    }
    console.log('All translations are fetched')
  } catch (error) {
    // 统一捕获错误,避免程序崩溃
    console.error('Fetch failed:', error)
  }
}

fetchAllTranslations()

额外优化说明

  • 使用GraphQL变量注入参数,避免直接字符串拼接引发的语法错误和注入风险;
  • 增加try/catch统一捕获错误,方便排查查询或文件写入时的问题;
  • 合并重复的文件写入操作,减少不必要的磁盘IO。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:07:39