Bootstrap

网络中断时接口status显示canceled,无法捕捉到状态进行相关操作

遇到的问题:如图所示,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 来实现一些特定的异步任务处理逻辑,比如设置超时、同时发起多个请求等。

;