提问者:小点点

当我的令牌需要刷新时,我如何暂停和继续?


我正在将大量数据发布到一个API,该API使用一个令牌,需要每30分钟刷新一次。

当令牌过期时,我如何暂停脚本,刷新令牌,然后从停止时开始继续?

到目前为止,我已经:

const post = await mergedItems.forEach((item, index) => {
    return new Promise((resolve, reject) => {
      const postBody = `{ "ItemShops": { "ItemShop": [{ "itemShopID": ${item.itemShopID}, "qoh": ${item.qoh} }]}}`
      setTimeout(() => {
      axios({
        url: `${lightspeedApi}/Account/${accountID}/Item/${item.id}.json`,
        method: 'put',
        headers: authHeader,
        data: postBody
      }).then(response => {
        if (response.status == 401) {
          refreshToken()
        } else {
        console.log(response.data) }
      }).catch(err => console.error(err))
    }, index * 10000)
    })
  })
}}

共1个答案

匿名用户

这是一个相当常见的问题,而且并行(哈!) 这里描述的。 您正在并行地启动多个请求,并且可以预期,一旦一个请求收到401响应,其他请求随后也会收到同样的响应。 这意味着它们都开始尝试刷新令牌,也是并行的。

下面是如何应用解决方案的粗略草图:

const makeRequest = async (opts) => {
  try {
    return axios(opts);
  catch (err) {
    // not axios throws on >=400 response code, not like fetch
    if (err.response && err.response.status === 401) {
      await refreshToken();
      return makeRequest(opts);
    else {
      raise err;
    }
  }
}

现在,您可以公开令牌得到刷新的承诺,并重用它以避免在一个请求已经在运行时发出多个请求:

let refreshPromise;

export const refreshToken = () => {
  if (!refreshPromise) {
    // start a refresh request only if one isn't in flight
    refreshPromise = axios(...).then((res) => {
      // ... reset token
      refreshPromise = null;
    });
  }
  return refreshPromise; 
};