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

Promise异步流程异常:旧XP获取与更新函数执行顺序及NaN问题

问题分析与修复方案

你的代码核心问题出在异步时序混乱和变量初始化时机错误,导致要么拿不到旧XP值,要么计算出NaN,具体问题点和修复方案如下:

核心问题点

  • new_xp和updated_XP在代码加载阶段就执行了,这时候old_Xp的异步请求还没完成,oldxpuser仍是undefined,所以new_xp = undefined +50会变成NaN。
  • 重复调用old_Xp():第一次调用没传UID参数(old_Xp())会触发请求错误,第二次单独调用old_Xp(8)但未关联后续update_Xp,导致两个异步请求并行,执行顺序完全不可控。
  • 依赖全局变量oldxpuser传递异步数据,极易出现时序问题,应该用Promise返回值传递数据,避免全局变量污染。

修复后的完整代码

// 获取用户旧XP的函数,移除全局变量,通过Promise直接返回结果
function old_Xp(UID) {
  return new Promise(function (resolve, reject) {
    redmine.users(UID, function(err, data) {
      if (err) {
        reject(err);
        return;
      }
      // 用find快速定位目标用户
      const targetUser = data.users.find(user => user.id === UID);
      if (!targetUser) {
        reject(new Error(`用户ID ${UID} 不存在`));
        return;
      }
      const oldxpuser = parseInt(targetUser.custom_fields[0].value);
      console.log("old xp: " + oldxpuser);
      resolve(oldxpuser);
    });
  });
}

// 更新XP的函数,改为接收新XP值作为参数
function update_Xp(UID, newXp) {
  return new Promise(function(resolve, reject) {
    const updated_XP = {
      user: {
        custom_fields: [{ id: 1, value: newXp }]
      }
    };
    redmine.update_user(UID, updated_XP, function(err, data) {
      if (err) {
        console.log(err);
        reject(err);
        return;
      }
      console.log('Updated !!');
      resolve(data);
    });
  });
}

// 正确的异步执行流程:先获取旧XP,计算新值,再执行更新
old_Xp(8)
  .then(oldxpuser => {
    const new_xp = oldxpuser + 50;
    console.log(new_xp);
    return update_Xp(8, new_xp);
  })
  .then(() => {
    console.log("ME: your promise has been resolved");
    check_XP(); // 确保更新完成后再执行检查
  })
  .catch(function(error) {
    console.log("Error occured ERROR:" + error);
  });

关键修复说明

  1. 移除全局变量:old_Xp通过resolve直接返回旧XP值,在then回调中接收,彻底避免全局变量的时序问题。
  2. 固定异步执行顺序:把new_xp计算、update_Xp调用都放到old_Xp的then回调内,确保只有拿到旧XP后才执行后续操作。
  3. 改造update_Xp:让它接收新XP值作为参数,内部生成更新对象,保证每次更新用的都是最新计算的值。
  4. 统一异步流程:只调用一次old_Xp(8),通过Promise链式调用严格控制执行顺序,同时将check_XP()放到更新完成后的回调中,确保检查的是最新数据。
  5. 优化用户查找逻辑:用Array.find()替代for循环,代码更简洁,同时新增用户不存在的错误处理分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:06:24