【问题标题】:Why does .catch() not catch reject() within Promise constructor within loop at an async function unless Error is passed?为什么 .catch() 不会在异步函数的循环内的 Promise 构造函数中捕获拒绝(),除非传递了错误?
【发布时间】:2018-01-07 21:37:39
【问题描述】:

给定

(async () => {
 const p = await new Promise((resolve, reject) => setTimeout(() => {
    reject(new Error(1))
  }, Math.floor(Math.random() * 1000))); return p})()
.then(data => console.log(data))
.catch(err => console.error(err));

Error() 记录在 .catch()

如果我们扩展模式以使用循环,Error 将记录在 .catch()

const fn = async(res, ...props) => {
  for (let prop of props) res.push(await prop())
  return res
}

const arr = [
  () =>
    new Promise((resolve, reject) => 
      setTimeout(() =>
        reject(new Error(1))
      , Math.floor(Math.random() * 1000))
    ),
  () => 
    new Promise((resolve, reject) => 
      setTimeout(() => 
        resolve(1) 
      , Math.floor(Math.random() * 1000))
    )
  ];

fn([], ...arr)
.then(data => console.log(data))
.catch(err => console.log(err));

如果我们使用循环调用多个返回 Promise 的函数并且没有明确地将 Error() 传递给 reject()Promise 构造函数 resolver 函数 .catch() 不会捕获错误,并且数组res 没有返回,只有传递给resolve()Promise 值可在

const fn = async(res, ...props) => {
  for (let prop of props) res.push(await prop())
  return res
}

const arr = [
  () =>
    new Promise((resolve, reject) => 
      setTimeout(() =>
        reject(1)
      , Math.floor(Math.random() * 1000))
    ),
  () => 
    new Promise((resolve, reject) => 
      setTimeout(() => 
        resolve(1) 
      , Math.floor(Math.random() * 1000))
    )
  ];

fn([], ...arr)
// what happened to our array `res` returned from `fn`?
.then(data => console.log(data))
// what happened to our rejected Promise?
.catch(err => console.log(err)); 

问题:

  1. Error() 没有显式传递给Promise 内的Promise 构造函数中的Promise 构造函数时,reject() 调用为什么不会传播到.catch()

  2. 为什么只有一个 Promise 值返回到 .then(),尽管当在循环中调用 reject() 函数中的一个 Promise 对象之一时从 async 函数返回一个数组Promise构造函数resolver函数?

【问题讨论】:

  • @JaromandaX 在.catch() 使用console.error() 而不是console.log() 的充分理由。您可以发表您的评论作为答案吗?

标签: javascript promise async-await ecmascript-2017


【解决方案1】:

当尝试代码时,例如使用Promise,并且预计会在.catch() 记录错误,明确将Error() 传递给@987654325 的reject(),最好使用相关消息作为参数@构造函数或Promise.reject();并使用console.error() 替换.catch() 处的console.log(),以便区分您期望记录为Error() 而不是已解决的Promise 值的错误,其中已解决和被拒绝的值可能恰好是一样的。

【讨论】:

    【解决方案2】:

    如果我们 [...] 没有明确地将 Error() 传递给 Promise 构造函数解析器函数 .catch()reject() 不会捕获错误

    当然,因为那时没有错误。但是catch 会捕获您传递给reject 的任何内容,即1 的值,它确实会被正确记录。

    【讨论】:

    • 问题是用户在读取响应时出错。为了防止将来出现用户错误:1)在预期错误时显式传递Error(),2)在.catch()处使用console.error()而不是console.log()来区分解析和拒绝Promise值,其中的值可能恰好是一样的。
    猜你喜欢
    • 2017-02-10
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2022-08-19
    • 1970-01-01
    • 2019-11-01
    相关资源
    最近更新 更多