错误消息 Uncaught (in promise) ,但在添加 catch 函数后我找不到问题所在

error message Uncaught (in promise) , but I can't find what's wrong with that after add catch function

为什么添加的捕获仍然根本不起作用?

function maxRequest(url = ``, times = 3) {
  // closure
  function autoRetry (url, times) {
    console.log('times = ', times);
    times--;
    return new Promise((resolve, reject) => {
      fetch(url).then(value => {
        if(value.status === 200) {
          console.log(`✅ `, value);
          resolve(value);
        } else {
          throw new Error(`❌  http code error: ${value.status }`);
        }
      }).catch((err) => {
        console.log(`❌  Error`, err);
        if (times < 1) {
          reject('  over max request times!');
        } else {
          autoRetry(url, times);
        }
      });
    });
  }
  return autoRetry(url, times);
}

maxRequest(`https://cdn.xgqfrms.xyz/json/badges.js`)
  .then(res => res.json())
  .then(json => {
      console.log('json =', json);
      return json;
  }, err => {
      console.log('error =', err);
      throw new Error(err);
  })
  .catch(err => console.log(`err =`, err))
  .finally(() => {
      console.log('whatever close loading...');
  });

您对 explicit Promise construction antipattern 的使用掩盖了您没有 return 来自 catch 块的事实。在重试情况下,您通过调用 autoRetry 创建了一个 second-try Promise,但您没有对其执行任何操作,因此 调用中的 catchmaxRequest 不会保护你,你最终会得到一个未捕获的被拒绝的 Promise。

function maxRequest(url = ``, times = 3) {
  // closure
  function autoRetry (url, times) {
    console.log('times = ', times);
    times--;
    // No more `new Promise`, just a chain.
    return fetch(url).then(value => {
      if(value.status === 200) {
        console.log(`✅ `, value);
        return value;
      } else {
        throw new Error(`❌  http code error: ${value.status }`);
      }
    }).catch((err) => {
      console.log(`❌  Error`, err);
      if (times < 1) {
        // Converted to rejection. You could still throw a
        // string, but throwing an Error is more idiomatic.
        throw new Error('  over max request times!');
      } else {
        // Make sure to return your Promise here. Don't worry
        // about returning a Promise; it's automatically wrapped
        // like Promise.resolve() does, so this chained-fetch()
        // Promise eventually gets the same result as the returned
        // recursive Promise.
        return autoRetry(url, times);
      }
    });
  }
  return autoRetry(url, times);
}

maxRequest(`https://cdn.xgqfrms.xyz/json/badges.js`)
  .then(res => res.json())
  .then(json => {
      console.log('json =', json);
      return json;
  }, err => {
      console.log('error =', err);
      throw new Error(err);
  })
  .catch(err => console.log(`err =`, err))
  .finally(() => {
      console.log('whatever close loading...');
  });

为了便于阅读,您可能还想更改变量名称,因此 times 不会同时用于外部和内部范围。您也可以将其改写为更短的 async 循环函数。