gpt4 book ai didi

javascript - 即使处理了拒绝的 promise ,也收到 `UnhandledPromiseRejectionWarning`

转载 作者:行者123 更新时间:2023-11-29 21:12:45 24 4
gpt4 key购买 nike

我构建了一个函数,它遍历包含同步代码和 PromisesGenerator:

module.exports = {


isPromise (value) {
return typeof value === 'object' && value !== null && 'then' in value;
},

runGen (generatorFunc, startValue) {

let that = this,
i = 0;

function *iterator(resolve, reject) {

let runGeneratorFunc = generatorFunc(startValue),
yieldedOut = {done: false},
yieldIn;

while (!yieldedOut.done) {
console.log(i++, 'Ready for next iteration');
if (that.isPromise(yieldedOut.value)) {
console.log(i++, 'Pass promise to KeepIterating');
yieldIn = yield yieldedOut.value;
console.log(i++, 'Received value from promise');

if(yieldIn instanceof Error){
console.log(i++, 'Value was instance of Error');
try {
yieldedOut = runGeneratorFunc.throw(yieldIn)
}
catch(err){
console.log(i++, 'Throw Error');
throw(yieldIn);
}
} else {
yieldedOut = runGeneratorFunc.next(yieldIn);
}
} else {
try {
yieldIn = yieldedOut.value;
yieldedOut = runGeneratorFunc.next(yieldIn);
}
catch(err) {
runGeneratorFunc.throw(err);
reject(err);
}
}
}
resolve(yieldedOut.value);
}

return new Promise(function (resolve, reject) {
var runIterator = iterator(resolve, reject);
(function keepIterating(yieldIn) {
let yieldedOutPromise = runIterator.next(yieldIn);

if (!yieldedOutPromise.done) {

yieldedOutPromise.value.then(function (fulfilledValue) {
console.log('never gets here');
keepIterating(fulfilledValue);
});

yieldedOutPromise.value.catch(function (err) {
console.log(i++, 'Rejected promise catched');
if (err instanceof Error) {
try {
console.log(i++, 'Rejected promise is instance of Error');
let yieldedOut = runIterator.next(err);
keepIterating(yieldedOut);
}
catch (err) {
console.log(i++, 'Error propagated back out');
yieldedOutPromise.value.catch(() => {})
reject(err);
}
} else {
try {
let yieldedOut = runIterator.next(new Error(err));
keepIterating(yieldedOut);
}
catch (err) {
reject(err);
}
}
})
}
})();
});
}
}

现在,当我使用这段代码导入并运行它时:

const md = require('./module');

function* dummy () {
yield Promise.reject(new Error('error1'));
}

md.runGen(dummy)
.catch(err => {
console.log(9, 'Finished!');
})

我将此记录到控制台:

0 'Ready for next iteration'
1 'Ready for next iteration'
2 'Promise yielded out'
3 'Rejected promise handled'
4 'Rejected promise instance of Error'
5 'Ready to handle promise value'
6 'Value was instance of Error'
7 'Throw Error'
8 'Error propagated back out'
9 'Finished!'
(node:9904) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: error1
(node:9904) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

除了有关 UnhandledPromiseRejectionWarning 的警告外,这一切都符合预期。我很困惑为什么我会收到此警告,因为据我所知,在代码中处理了被拒绝的 Promise

我忽略了什么?

最佳答案

What am I overlooking?

您的 yieldedOutPromise.value.then 调用正在创建一个新的 promise ,如果 yieldedOutPromise.value 拒绝,那么它也将被拒绝。您通过 .catch 处理 yieldedOutPromise.value 上的错误并不重要,周围仍然存在被拒绝的 promise ,并且将报告该 promise 。

您基本上是在拆分您的 promise 链,这导致每一端都需要一个错误处理程序。但是,您根本不应该拆分任何东西。而不是

promise.then(onSuccess);
promise.catch(onError);

你应该使用的反模式

promise.then(onSuccess, onError).…

哦,当你在做的时候,avoid the Promise constructor antipattern .就这样

module.exports = function runGen (generatorFunc, startValue) {
return Promise.resolve(startValue).then(generatorFunc).then(generator => {
return keepIterating({done: false, value: undefined});
function keepIterating({done, value}) {
if (done) return value;
return Promise.resolve(value).then(fulfilledValue =>
generator.next(fulfilledValue)
, err =>
generator.throw(err)
).then(keepIterating);
}
});
};

关于javascript - 即使处理了拒绝的 promise ,也收到 `UnhandledPromiseRejectionWarning`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40963671/

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