使用Promise的链式HTTPS请求执行顺序异常问题排查
问题分析与解决
核心问题:Promise封装错误导致请求未按预期顺序执行
你的问题出在前端Promise的错误封装,没有等待fetch请求完成就触发后续操作,导致/Total请求可能在/Add请求处理完成前就发送,从而拿到旧值。
错误点1:PutAddValuePromise未等待fetch完成
当前代码中,PutAddValuePromise调用fetch后立刻执行myResolve(),完全没等待PUT请求完成:
let PutAddValuePromise = function (addValue) { return new Promise(function (myResolve, myReject) { fetch(uriAdd + '?value=' + addValue, { method: 'PUT' }) .catch(error => myReject('Unable to add value.', error)); // 直接resolve,未等待fetch请求结束 myResolve(); }) };
这会导致.then(() => UpdateDisplay())在PUT请求还没处理完时就触发,此时发起/Total请求自然可能拿到旧数据。
错误点2:GetTotalValuePromise的冗余封装
这个函数手动包裹Promise完全没必要,且错误地把fetch返回的Promise直接传给myResolve,写法不规范易混淆。
修复方案
1. 修正PutAddValuePromise,等待fetch完成
直接返回fetch的Promise即可,无需手动创建新Promise:
let PutAddValuePromise = function (addValue) { return fetch(uriAdd + '?value=' + addValue, { method: 'PUT' }) .catch(error => { throw new Error('Unable to add value. ' + error); }); };
这样PutAddValuePromise(value).then(...)会严格等待PUT请求完成后才执行后续的UpdateDisplay。
2. 简化GetTotalValuePromise
直接返回fetch的Promise链,去掉冗余的Promise包裹:
let GetTotalValuePromise = function () { return fetch(uriTotal) .then(response => response.text()) .catch(error => { throw new Error('Unable to get total. ' + error); }); };
3. 额外优化:处理HTTP错误状态码
注意fetch只有网络错误才会触发catch,HTTP错误(如4xx/5xx)不会,可在.then里判断响应状态:
let PutAddValuePromise = function (addValue) { return fetch(uriAdd + '?value=' + addValue, { method: 'PUT' }) .then(response => { if (!response.ok) { throw new Error(`HTTP错误!状态码: ${response.status}`); } }) .catch(error => { throw new Error('Unable to add value. ' + error); }); };
服务器端验证
你的ASP.NET Controller逻辑正常:Session的读写操作是同步的,手动调用GetTotal()能拿到正确值也证明了这一点。问题完全出在前端Promise的错误使用,未保证请求的执行顺序。
内容的提问来源于stack exchange,提问作者Perringaiden
相关产品推荐
相关产品推荐

