gpt4 book ai didi

javascript - 如果有 Uncaught Error ,有什么方法可以使 promise 被拒绝?

转载 作者:行者123 更新时间:2023-12-05 03:30:18 25 4
gpt4 key购买 nike

很容易忘记在异步函数中使用 try/catch,或者在使用 promises 时无法捕获所有可能的错误。这可能会导致无休止的“等待”,因为 Promise 永远不会被解决或拒绝。

如果存在 Uncaught Error ,是否有任何方法(例如通过代理或更改 promise 构造函数)导致异步函数或其他 promise 被拒绝?下面显示了一个一般情况。我正在寻找某种方法来克服“等待”(如抛出错误时应拒绝“p”)而不修复“badPromise”。

async function badPromise() {
const p = new Promise((res) => {
delayTimer = setTimeout(() => {
console.log('running timeout code...');
if (1 > 0) throw new Error('This is NOT caught!'); // prevents the promise from ever resolving, but may log an error message to the console
res();
}, 1000);
});
return p;
}

(async () => {
try {
console.log('start async');
await badPromise();
console.log('Made it to the end'); // never get here
} catch (e) {
console.error('Caught the problem...', e); // never get here
}
})();```

最佳答案

在未捕获的同步错误的情况下,Promises 已经拒绝:

  • in a Promise constructor , 对于同步(抛出)错误

    If an error is thrown in the executor, the promise is rejected.

  • in onFulfilled and onRejected functions ,例如 thencatch

    If a handler function: [...] throws an error, the promise returned by then gets rejected with the thrown error as its value.

  • in async functions

    Return Value: A Promise which will be resolved with the value returned by the async function, or rejected with an exception thrown from, or uncaught within, the async function.

你这里的问题不是 Promise 不处理 Uncaught Error ,它根本上是因为你的错误是异步的:就 Promise 而言,它的执行函数是一个成功的小函数,它调用 setTimeout。当您的 setTimeout 处理程序运行并失败时,它会使用与 Promise 对象或其函数无关的自己的堆栈来执行此操作; badPromisep 不存在于您的 setTimeout 处理程序中,除了处理程序通过闭包包含的 res 引用。在问题“Handle error from setTimeout”中,在 setTimeout 处理程序中捕获错误的技术都涉及编辑或包装处理程序,并且根据 HTML spec for timers步骤 9.2 没有机会捕获或插入调用传递到 setTimeout 的函数的错误情况。

除了编辑 badPromise几乎您无能为力。


备选方案:

  • 依次修改/覆盖Promise构造器和setTimeout方法,包装Promise构造器方法保存resolve/reject 参数,然后包装全局 setTimeout 方法,以便使用 try/catch 包装 setTimeout 处理程序调用新保存的 reject 参数。 由于更改这两个全局服务的脆弱性,我强烈建议不要使用此类解决方案。

  • 创建一个包装高阶函数(即返回一个函数的函数),它接受拒绝回调并包装 setTimeout 调用。这在技术上是对 badPromise 的编辑,但它确实封装了正在发生的变化。它看起来像这样:

    function rejectOnError(rej, func) {
    return (...args) => {
    try {
    return func(...args);
    } catch (e) {
    rej(e);
    }
    };
    }

    async function badPromise() {
    const p = new Promise((res, rej) => { // save reject
    delayTimer = setTimeout(rejectOnError(rej, () => { // to use here
    console.log('running timeout code...');
    if (1 > 0) throw new Error('Now this is caught');
    res();
    }), 1000);
    });
    return p;
    }

    badPromise().catch(x => console.error(`outer: ${x}`));
    console.log('bad promise initiated');

关于javascript - 如果有 Uncaught Error ,有什么方法可以使 promise 被拒绝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70856589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com