首页 > 解决方案 > 承诺拒绝 - 超时记录放置

问题描述

我有一个超时的承诺竞赛实施。我想在超时的情况下记录超时错误。

问题是即使获取成功它也会记录,因为它并行运行并且在超时后仍然执行。

在哪里放置以防万一errorLogger.info(message)它不会被执行non-timeout?我想我说错了,所以它在实际拒绝之前就输出了。

return Promise.race([
   fetch(url, options)
  .then(function (response) {
    if (response.status >= 400) {
      const message = `fetch-utility.js: bad server response while fetching url=${url} with options=${options}.`;


      errorLogger.error(`${message} Response: status=${response.status} statusText:${response.statusText}.`);

      throw new BadServerResponseException(message, response.status);
    }
    return response;
  }),
  new Promise((_, reject) =>
    setTimeout(() => {
      const message = `fetch-utility.js: timeout happened while fetching details url=${url} with options=${options}. 
  The timeout set is ${timeout}.`;

      // TODO: this gets logged even the parallel wins - need to see better way to log this
      // errorLogger.error(message);

      reject(new TimeoutException(message));
    }, timeout),
  ),
]);

标签: javascriptpromisees6-promise

解决方案


您不应该在这两个结构中记录错误,因为它确实会被调用。

相反,您可以将 a thenand链接到由 .catch返回的承诺上Promise.race。因此,您可以将论点保持在race非常小的范围内,并将逻辑移到外部。

就像是:

return Promise.race([
    fetch(url, options),
    new Promise((_, reject) => setTimeout(() => reject("timeout"), timeout))
]).catch(function(error) {
    if (error === "timeout") {
        const message = "timeout happened";
        errorLogger.error(message);
        throw new TimeoutException(message);
    } else {
        const message = "fetch failed";
        errorLogger.error(message);
        throw new FetchException(message);
    }
}).then(function (response) {
    if (response.status >= 400) {
        const message = "bad response";
        errorLogger.error(message);
        throw new BadServerResponseException(message, response.status);
    }
    return response; // Success within timeout!
});

推荐阅读