首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么承诺错误捕获的时间比setTimeout错误晚?

为什么承诺错误捕获的时间比setTimeout错误晚?
EN

Stack Overflow用户
提问于 2022-10-27 07:52:22
回答 1查看 57关注 0票数 0

我们都知道微任务比宏任务执行得更早,但是在错误捕获过程中会出现意想不到的结果。下面是代码:

代码语言:javascript
复制
window.onerror = e => {
    console.log('=====onerror', e)
}
window.onunhandledrejection = e => {
    console.log('=====unhandledrejection', e.reason)
}

function Test() {
    function cacheTest() {
        new Promise((resolve, reject) => {
            reject('promiseError')
        }).catch(e => {
            console.log('start throw promiseError')
            throw e
        })
        // Promise.reject('promiseError')
        setTimeout(() => {
            console.log('start throw setTimeoutError')
            throw new Error('setTimeoutError')
        }, 1)
        console.log('start throw syncError')
        throw new Error('syncError')
    }
    return (
        <div id="test-performance" onClick ={cacheTest}>
            Test Insight:Cache Exception
        </div>
    )
}
ReactDOM.render( <Test/>, document.getElementById('root'))
代码语言:javascript
复制
<script crossorigin src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script crossorigin src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>
<div id="root"></div>

我得到了这个:

代码语言:javascript
复制
start throw syncError
Inline Babel script:3 =====onerror Uncaught Error: syncError

start throw promiseError
Inline Babel script:19 start throw setTimeoutError
Inline Babel script:3 =====onerror Uncaught Error: setTimeoutError

=====unhandledrejection 

但是,当我将setTimeout改为1时,一切都是正常的:

代码语言:javascript
复制
setTimeout(() => {
    console.log('start throw setTimeoutError')
    throw new Error('setTimeoutError')
}, 1)

它的工作是:

代码语言:javascript
复制
start throw syncError
Inline Babel script:3 =====onerror Uncaught Error: syncError

start throw promiseError
Inline Babel script:6 =====unhandledrejection 

start throw setTimeoutError
Inline Babel script:3 =====onerror Uncaught Error: setTimeoutError

是因为setTimeout0有一些特殊的机制吗?

EN

回答 1

Stack Overflow用户

发布于 2022-10-27 09:02:46

看看它是如何在浏览器中工作的。我是node.js开发人员,我知道它在node.js中是如何工作的

我认为- setTimeout(0)使用setImmediate()函数,并在Promise处理之前调用微任务。

setImmediateprocess.nextTick函数存在于node.js中,所以,如果您认为setImmediate已经调用了,而process.nextTick (在下一个滴答中)不是真的!

node.js中有一个错误的行为,因为当开发人员开发架构时--他们犯了一个错误,混淆了setImmediateprocess.nextTick函数行为。

因此,process.nextTickPromise's之前提交了微任务。

我已经为node.js重新编写了作者的代码,它的工作原理就像我前面所说的!

代码语言:javascript
复制
function cacheTest(milis) {
  new Promise((resolve, reject) => {
    reject('promiseError')
  }).catch(e => {
    console.log('start throw promiseError')
    throw e
  });

  // Promise.reject('promiseError')
  if (milis === 0) {
    process.nextTick(() => {
      console.log('start throw setTimeoutError')
      throw new Error('setTimeoutError');
    });
  } else {
    setTimeout(() => {
      console.log('start throw setTimeoutError');
      throw new Error('setTimeoutError');
    }, milis)
  }
  console.log('start throw syncError')
  throw new Error('syncError')
}

try {
  cacheTest(0);
} catch(err) {
  console.log(err);
}

尝试调用cacheTest(0)cacheTest(1)

你会看到像作者一样的结果。(但只有两个错误,因为取消处理程序错误已经使进程崩溃)

因此,在第一种情况下,第二种错误来自process.nextTick(),第二种情况是来自Promise

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74218551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档