为什么我的 Promise.reject 在被捕获时仍然抛出错误?

问题描述 投票:0回答:1
我正在尝试测试以下代码基本代码片段。目标是针对记录中的每条记录运行异步

consumerFunction

(运行时间根据传入的记录而变化很大)并返回已解决承诺的列表。

消费记录:

exports.consumeRecords = async (args) => { let { records, consumerFunction } = args let settledPromises = await Promise.allSettled( records.map(async (record, i) => { return consumerFunction(record) .then(async (result) => { console.log(`${thisTaskName} consumer function returned :>> `, result) return Promise.resolve(result) }) .catch(async (err) => { console.error(`${thisTaskName} consumer function error ${err}`) return Promise.reject("ERR: ", err) }) }) ) return settledPromises }
为了测试这个,我正在使用 Jest 测试。我有一个模拟消费者函数,

mockAsyncConsumerFunction

,它在每次返回时都设置了延迟......要么是已解决的承诺,要么是被拒绝的承诺。我希望能够测试所有的承诺是否会并行运行,直到完成。

test("When a function rejects lst, the promises still all settle", async () => { function delay(t, v) { return new Promise((resolve) => setTimeout(resolve, t, v)) } let mockAsyncConsumerFunction = async (recordBody) => { if (recordBody.fake === 111) { return delay(30, Promise.resolve("111 returned")) } else if (recordBody.fake === 222) { return delay(20, Promise.resolve("222 returned")) } else { return delay(10, Promise.reject("333 error!")) } } let returnedPromise = await utils.consumeRecords({ consumerFunction: mockAsyncConsumerFunction, records: [{ fake: 111 }, { fake: 222 }, { fake: 333 }] }) expect(returnedPromise).toStrictEqual([ { status: "fulfilled", value: "111 returned" }, { status: "fulfilled", value: "222 returned" }, { reason: "ERR: ", status: "rejected" }, ]) })
这次测试的结果是

[UnhandledPromiseRejection: 此错误源自于抛出 在没有 catch 块的异步函数内部,或者通过拒绝 未使用 .catch() 处理的承诺。承诺被拒绝 “333 错误!”的原因。] { 代码:'ERR_UNHANDLED_REJECTION' }

注意,承诺正在拒绝我希望它拒绝的价值。我在 forEach 的消费者函数调用中有一个 '.catch()',但它似乎没有捕捉到错误。

编辑:当我将 consumeRecords 函数中的

return Promise.reject('ERR: ', err)

 行更改为 
return err
 时,我仍然遇到相同的错误。

EDIT2:当我在延迟函数的末尾添加

.catch(()=>null)

 时,我不再收到“未处理的拒绝”错误......但我的 Jest 测试和 settledPromises 数组中仍然收到“抛出”消息通过拒绝被“满足”(即:我基本上只是解决而不是拒绝)

javascript asynchronous jestjs promise
1个回答
0
投票
根据评论中收到的建议,我了解到调用

Promise.resolve()

 的值为 
Promise.reject('msg')
 会导致未处理的拒绝。第一条评论(投票 4 次)说这是返回 Promise.reject() 的结果是不正确的。

因此我将延迟功能更改为:

async function delay(t, v) { return new Promise((resolve, reject) => { if(typeof v ==='string') { return setTimeout(reject, t, v) } else { return setTimeout(resolve, t, v) } }) }
我的 mockAsyncConsumerFunction 对此:

let mockAsyncConsumerFunction = async (recordBody) => { if (recordBody.fake === 111) { return delay(30, Promise.resolve("111 returned")) } else if (recordBody.fake === 222) { return delay(20, Promise.resolve("222 returned")) } else { return delay(10, "333 error!") //changed from Promise.reject("333 error!") } }
    
© www.soinside.com 2019 - 2024. All rights reserved.