遇到的问题:如图所示,loading状态栏无法关闭,因为.then和.catch还有.finally 中都无法捕捉到接口canceled的状态,导致一直在loading状态,无法进行操作关闭弹框这一步。
产生原因:客户端 在服务器响应前关闭了连接。(网络中断或者网卡导致的) 网络中断后,Promise可能没有正确 reject,因此 catch 块内的逻辑不会执行。
解决思路:尝试在网络中断的情况下手动 reject Promise,以确保 catch 块内的逻辑被执行。
解决办法:使用 Promise 的 race 方法: 可以同时发起请求和设置一个超时 Promise,使用 Promise.race 来等待其中一个 Promise 完成。当网络连接断开或请求超时时,即可关闭加载状态。
代码如下:
// 创建超时抛出reject
const networkDisconnectedPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Network disconnected'));
}, 180000); // 设置超时时间为3分钟
});
// 当前真实需要调用的接口(Http.post是基于wx.request封装的的请求方法)
const requestPromise = Http.post({
url: showStep ? `/mediator/mediation_case/update/${id}` : '/mediator/mediation_case/add',
data: { ...form },
});
Promise.race([requestPromise, networkDisconnectedPromise]).then(() => {
// 这里写接口调用成功后的操作(接口状态正常,后端有响应)
}).catch(error => {
console.log("error",error);
// 请求失败canceled处理
if (error.message === "Network disconnected") {
console.log("请求失败canceled处理");
} else {
console.error('请求失败:', error);
}
}).finally(() => {
// 不管成功或失败都会进入到finally这一步,所以在这里统一关闭loading状态
setTimeout(() => {
wx.hideLoading();
}, 500);
});
拓展:关于 Promise 的 race 方法详解
Promise.race
是 Promise 提供的一个静态方法,它接收一个可迭代对象(通常是一个数组),并返回一个新的 Promise。这个新的 Promise 的状态和第一个完成的 Promise 的状态一致,无论是成功还是失败。
具体来说,Promise.race
方法会等待传入的多个 Promise 中的任意一个状态发生改变,一旦有一个 Promise 状态发生改变(无论是成功还是失败),Promise.race
就会返回一个新的 Promise,并将这个状态传递给这个新的 Promise。这样,我们就可以通过 Promise.race
来实现一些特定的异步任务处理逻辑,比如设置超时、同时发起多个请求等。