代码之家  ›  专栏  ›  技术社区  ›  Kognise

如何发现是否在承诺的陷阱中

  •  0
  • Kognise  · 技术社区  · 7 年前

    我写了一些非常简单的错误处理代码,可以完美地处理同步操作。我不得不修改 throwError 函数的作用是在异步操作中表现出我想要的方式,但现在它不能像我期望的那样在同步操作中工作。如何检测函数是否在承诺的catch块中被调用以更改行为?

    以下是同步操作的良好代码:

    const errorHandler = () => console.log('Woot, handled error')
    const throwError = (error) => {
      throw error
    }
    
    try {
      throwError(new Error('Blah blah'))
      console.log('This should not be reached')
    } catch(error) {
      errorHandler(error)
    }

    以下是非常适合异步操作的代码:

    const errorHandler = () => console.log('Blah blah')
    const throwError = (error) => {
      errorHandler(error)
    }
    
    const loadStuff = () => new Promise((_, reject) => {
      console.log('Loading stuff')
      setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
    })
    
    try {
      loadStuff().catch(throwError)
    } catch(error) {
      errorHandler(error)
    }

    但是如果你把异步 投掷误差 第二个console.log执行的同步代码中的代码。如果你把同步 投掷误差 在异步代码中,它给出了一个未处理的承诺拒绝错误。

    我怎么能,只有一个 投掷误差 函数,知道它是在兑现承诺还是被手动调用以在调用之间切换 errorHandler 直接和 throw 这个错误?假设只有 投掷误差 最后一个 catch 子句可以访问 错误处理程序 .

    由于某种原因,这个问题很难写,可能措词都很奇怪,我很感谢任何澄清性的编辑。

    0 回复  |  直到 7 年前
        1
  •  0
  •   Tabare    7 年前

    问题在于:

    但如果将异步throwerror代码放入同步代码中,则会执行第二个console.log。如果您将同步throwerr放入异步代码中,它会给出一个未处理的承诺拒绝错误。

    这可能是一些事情需要事先澄清,这两个功能 投掷误差 当一个收到一个错误并抛出它时,您所写的执行完全不同的操作,而另一个只是记录 “胡说八道” .

    另一方面,在代码中

    const errorHandler = () => console.log('Blah blah')
    const throwError = (error) => {
      errorHandler(error)
    }
    
    const loadStuff = () => new Promise((_, reject) => {
      console.log('Loading stuff')
      setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
    })
    
    try {
      loadStuff().catch(throwError)
    } catch(error) {
      errorHandler(error)
    }

    如果我们将throwerror函数更改为等于第一个函数,那么代码将如下所示:

    const errorHandler = () => console.log('Blah blah')
    const throwError = (error) => {
       throw error
    }
    
    const loadStuff = () => new Promise((_, reject) => {
      console.log('Loading stuff')
      setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
    })
    
    try {
      loadStuff().catch(throwError)
    } catch(error) {
      errorHandler(error)
    }

    这里所发生的是,一旦loadStuff被拒绝,就会执行throwerRor函数,从而引发错误,但它不会在try/catch语句中作为 尝试 不要因为loadstuff返回承诺而抛出错误, 在装载物的捕获中发生的事情与try/catch的捕获无关。 因为它有不同的 scope . 事实上,两个捕获都可以同时执行,如果它是这样写的:

    const errorHandler = () => console.log('Blah blah')
    const throwError = (error) => {
       console.log('another catch')
       throw error
    }
    
    const loadStuff = () => new Promise((_, reject) => {
      console.log('Loading stuff')
      setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
    })
    
    try {
      loadStuff().catch(throwError)
      throw new Error('my Error')
    } catch(error) {
      errorHandler(error)
    }

    说了那么多 假设 每次抛出一个错误时,您都希望以相同的方式处理它,可能的解决方案是将其编写为:

    const errorHandler = () => console.log('Blah blah')
    
    const loadStuff = () => new Promise((_, reject) => {
      console.log('Loading stuff')
      setTimeout(() => reject(new Error('Oh no, an error!')), 1000)
    })
    
    try {
      loadStuff().catch(errorHandler)
    } catch(error) {
      errorHandler(error)
    }