const main = async () => {
const foo = new Promise(() => {});
foo
.catch((error) => {
console.log('error', error);
})
.then((response) => {
console.log('response', response);
});
};
main();
假设上面的代码片段,其中foo
是某些第三方代码返回的错误处理的Promise:我如何检测到foo
永远不会被解决?
出于某种背景,我正在尝试在第三方软件包中解决此bug问题。
答案 0 :(得分:2)
我认为这是最接近检测Promise是否能够解决的人。
const asyncHooks = require('async_hooks');
const timeoutIdlePromise = async (createPromise, maximumIdleTime) => {
return new Promise(async (resolve, reject) => {
let Timeout;
const parentAsyncIds = [];
const asyncHook = asyncHooks.createHook({
init: (asyncId, type, triggerAsyncId) => {
if (parentAsyncIds.includes(triggerAsyncId)) {
if (Timeout) {
Timeout.refresh();
}
if (!parentAsyncIds.includes(asyncId)) {
parentAsyncIds.push(asyncId);
}
}
},
});
Timeout = setTimeout(() => {
reject(new Error('Idle promise timeout.'));
asyncHook.disable();
}, maximumIdleTime);
asyncHook.enable();
// Force new async execution context.
await null;
const executionAsyncId = asyncHooks.executionAsyncId();
parentAsyncIds.push(executionAsyncId);
try {
const result = await createPromise();
resolve(result);
} catch (error) {
reject(error);
} finally {
asyncHook.disable();
}
})
};
// Rejected with Idle promise timeout.
timeoutIdlePromise(() => {
return new Promise((resolve) => {
});
}, 1000);
// Resolved.
timeoutIdlePromise(() => {
return new Promise((resolve) => {
setTimeout(() => {
setTimeout(() => {
setTimeout(() => {
resolve();
}, 500);
}, 500);
}, 500);
});
}, 1000);
async_hooks
用于检查诺言是否正在创建任何异步事件(以及由诺言创建的异步事件本身是否会创建其他异步事件,等等),只要诺言中存在某些异步活动(例如事件监听器,网络活动,超时),它将继续挂起。如果maximumIdleTime
中没有异步活动,则会引发错误。
我已将以上逻辑抽象到模块timeout-idle-promise
中。
import {
timeoutIdlePromise,
TimeoutError,
} from 'timeout-idle-promise';
// Rejected with TimeoutError error.
timeoutIdlePromise(() => {
return new Promise((resolve) => {
});
}, 1000);
// Resolved.
timeoutIdlePromise(() => {
return new Promise((resolve) => {
setTimeout(() => {
setTimeout(() => {
setTimeout(() => {
resolve();
}, 500);
}, 500);
}, 500);
});
}, 1000);