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

JS Promise的resolve/reject失效?国旗匹配功能错误处理求助

问题分析与解决

核心问题

你代码里的fetch是异步任务,而判断found的代码是同步执行的——发起fetch请求后,还没等接口返回数据、还没来得及修改found的值,就直接执行了if(found)的判断,这时候found还是初始的false,所以每次都会触发reject。

修复方案

1. 把resolve/reject逻辑移到异步回调内

等fetch请求完成、数据处理完之后,再根据匹配结果决定是resolve还是reject,而不是在发起请求后立刻判断。

2. 移除全局found变量,避免状态污染

全局变量会保留上一次点击的状态,改用局部变量来记录是否找到匹配项。

3. 去掉正则的g修饰符

带g的正则表达式会维护一个lastIndex指针,多次调用test时会从上次结束的位置开始匹配,容易出现误判。

4. 复用首次请求的国家数据

页面加载时已经请求过一次API,没必要每次点击都重新请求,直接用之前存储的数据即可。

修改后的完整代码

const selector = document.getElementById('input')
const btn = document.getElementById('btn')
const flag = document.getElementById('content')

const API = 'https://restcountries.com/v2/all'
// 存储完整的国家对象,方便后续直接使用
let countries = []

// 页面加载时仅请求一次API
fetch(API).then(data => data.json()).then(data => {
    countries = data
    console.log('国家数据加载完成')
})

btn.addEventListener('click', () => {
    const info = selector.value.trim()
    // 空输入直接提示
    if (!info) {
        console.error('请输入国家名称')
        return
    }
    
    // 用局部变量记录匹配状态,避免全局污染
    let found = false
    // 只保留不区分大小写的修饰符,去掉g避免匹配异常
    const reg = new RegExp(info, 'i')
    
    // 复用已加载的国家数据,无需重复请求API
    countries.forEach(element => {
        if (reg.test(element.name)) {
            flag.style.backgroundImage = `url(${element.flag})`
            flag.style.backgroundPosition = 'center'
            flag.style.backgroundSize = 'cover'
            found = true
            // 找到第一个匹配项就终止遍历,提升效率
            return
        }
    })

    const p1 = new Promise((res, rej) => {
        found ? res('匹配成功') : rej('未找到匹配的国家')
    })

    p1.then(msg => console.log(msg)).catch(err => console.error(err))
})

额外优化点

  • 加入空输入判断,避免无效匹配操作
  • 找到第一个匹配项后终止遍历,减少不必要的循环开销
  • 复用已请求的数据,大幅提升点击响应速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:18:13