当前位置: 首页 > 知识库问答 >
问题:

为什么此示例抛出UnhandledPromiserEjectionWarning?[副本]

章子航
2023-03-14

NodeJS版本8.11-警告是“此错误源于在没有catch块的情况下抛出异步函数,或者拒绝未用.catch()处理的promise。”

这两个都不是真的,您可以通过检查我的测试用例看出这一点:

const DEMONSTRATE_FAILURE = false

async function doPromises() {
    try {
        if (DEMONSTRATE_FAILURE) {
            // This causes UnhandledPromiseRejectionWarning warnings:

            const brokenPromises = [createPromises(), createPromises()]

            await brokenPromises[0]
            await brokenPromises[1]

        } else {
            // This works fine:
            await createPromises()
            await createPromises()
        }
    } catch(err) {
        process.stdout.write("x")
    }
}

// Create 10 promises, of which 50% will reject after between 0 and 1000ms
function createPromises() {
    let badPromises = []
    for (let x = 0; x < 10; x++) {
        badPromises.push(new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() > 0.5) {
                process.stdout.write("-")
                reject("rejected!")
            } else {
                process.stdout.write("+")
                resolve()
            }
        }, Math.round(Math.random() * 1000))
        }))
    }

    return Promise.all(badPromises)
}


(async function main() {
    while (true) {
        await doPromises()
    }
})()

翻转demonstrate_failure标志,查看相同的代码运行时是否有错误。

共有1个答案

陆弘光
2023-03-14

问题是,一旦有一个awaitedpromise被拒绝,就会引发错误,代码将从try中的await brokenpromises[0]行移动到catch。因此,brokenpromons[0]引发的错误现在已经被正确捕获。但是,brokenpromess[1]中被拒绝的promise还没有被处理!(如果try块通过[0]并到达[1],然后await brokenpromospores[0]将引发一个错误,该错误将被捕获,但解释器不知道这一点,则会处理该错误)

下面是一个小得多的示例,它说明了您最初的问题(打开浏览器控制台查看拒绝,它在堆栈代码段控制台中是不可见的):

const makeProm = () => new Promise((_, reject) => setTimeout(reject, 500));

console.log('will be uncaught:');
// Unhandled rejection:
(async () => {
  try {
    const proms = [makeProm(), makeProm()];
    await proms[0];
    await proms[1];
  } catch(e){}
})();

// Works:
setTimeout(async () => {
  console.log('going to be caught:');
  try {
    await makeProm();
    await makeProm();
  } catch(e){ console.log('caught'); }
}, 1000);
 类似资料:
  • 问题内容: 这是我的XML文件: 我做了两个类来解析它(Fields.java和Field.java): 和 但是我得到这个例外。 我不明白为什么会出现这种异常。异常在这里: 我使用的是JDK 1.6_0.0.7。谢谢。 问题答案: 例外是由于您的JAXB(JSR-222)实现认为存在两个名称相同的事物(一个字段和一个属性)。您的用例有两个选项: 选项#1-使用以下注释字段 如果要注释该字段,则应

  • 这是我的申请 数据源:类型:com.zaxxer.hikari.HikariDataSource主要: 这是我的入门: 这是我的例外: 2017-11-21 10:10:33.126线程“main”中的表现:java.lang.运行时异常: java.lang.ClassCastException: 无法将 com.mysql.cj.jdbc.Driver to javax.sql.DataSou

  • 问题内容: final Multimap terms = getTerms(bq); for (Term t : terms.keySet()) { Collection C = new HashSet(terms.get(t)); if (!C.isEmpty()) { for (Iterator it = C.iterator(); it.hasNext();) { BooleanClause

  • 问题内容: 我试图将两个’Employee’对象添加到TreeSet中: 但是它抛出一个ClassCastException: 但是,如果我仅将一个对象添加到TreeSet中: 或者,如果我改用HashSet: 那就成功了。为什么会发生异常,我该如何解决? 问题答案: 要么必须实现,或者你需要提供一个比较创建时。 在文档中对此进行了详细说明: 插入排序集中的所有元素都必须实现接口(或被指定的比较器

  • 问题内容: 将字符串解析为字节时出现异常 问题答案: 这是因为默认的parse方法要求使用十进制格式的数字来解析十六进制数字,请使用以下parse: 其中16是解析的基础。 至于您的评论,您是对的。字节的最大值为0x7F。因此,您可以将其解析为并执行二进制与操作以获得LSB,即您的字节: