【问题标题】:Failing fetch in a Promise.all not catching error在 Promise.all 中无法获取错误
【发布时间】:2020-03-27 12:23:48
【问题描述】:

我有多个 JSON 要加载,并且必须检查它们是否都被正确提取。所以我使用 Promise.all 来等待所有的fetch

第一个 valid.json 存在,而不是第二个,所以第二个 fetch 以 404 结尾。 但是尽管有Promise.rejectPromise.all 仍然记录Success! 而不是抛出最后一个错误。

关于Promise.all 的工作原理,我是否遗漏了什么?

const json_pathes = [
    'valid.json',
    'not_valid.json'
];

function check_errors(response) {
    if (!response.ok) {
        Promise.reject('Error while fetching data');
        throw Error(response.statusText + ' (' + response.url + ')');
    }
    return response;
}

Promise.all(json_pathes.map(url =>
    fetch(url)
        .then(check_errors)
        .then(response => response.json())
        .catch(error => console.log(error))
))
.then(data => {
    console.log('Success!', data);
})
.catch(reason => {
    throw Error(reason);
});

// Console:
// Error: "Not Found (not_valid.json)"
// uncaught exception: Error while fetching data
// Array [ […], undefined ]

(当然检查了所有类似的问题,但没有任何帮助????)


edit - 在以下答案后修复代码:

const json_pathes = […]
Promise.all(json_pathes.map(url =>
    fetch(url)
        .then(response => {
            if (!response.ok)
                throw Error(response.statusText + ' (' + response.url + ')');
            return response;
        })
        .then(response => response.json())
        .catch(error => {
            throw error;
        })
))
.then(data => {
    // Success
})
.catch(error => {
    throw error;
});

【问题讨论】:

    标签: javascript promise fetch


    【解决方案1】:

    使用 .catch() 方法时必须再次抛出错误,否则错误将被静音

    Promise.all(
      json_paths.map(url => 
        fetch(url)
          .then(response => response.json())
          .catch(err => {
            console.log(err);
            throw err
          })
      )
    ).then(data => {
      // all promise resolved
      console.log(data)
    }).catch(err => {
      // some promise may not be resolved
      console.log(err)
    })
    
    

    【讨论】:

      【解决方案2】:

      这个电话:

       .catch(error => console.log(error))
      

      ...将返回一个已履行的承诺,而不是一个被拒绝的承诺。每当您将拒绝视为拒绝并希望它冒泡时,您应该明确地这样做:

       .catch(error => {
             console.log(error);
             throw error; // cascade...
       })
      

      顺便说一句,这根本没有效果

       Promise.reject('Error while fetching data');
      

      ... 因为您不会对这个新创建的、被拒绝的承诺做任何事情。

      【讨论】:

      • 感谢您的详细解释!
      猜你喜欢
      • 2019-01-21
      • 1970-01-01
      • 2018-12-09
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      相关资源
      最近更新 更多