javascript - 在 Node 中运行后台进程的最佳实践?
问题描述
比如说我有以下代码,一个简单的 UI 测试。
async function testMyCoolUI() {
await uiFramework.openMyApp(url);
await sleep(2000);
await uiFramework.clickButtonX();
await uiFramework.clickButtonY();
}
现在添加了一个新要求。在测试期间的任何时候,屏幕上都会出现一个弹出窗口,上面写着“你是机器人吗?”,我们必须选择“否”。
您将如何构建您的测试,以使这个“过程”可以在测试的背景中持续运行,并注意这个弹出窗口?我最初的想法是启动一个异步函数轮询弹出窗口,但不要等待testMyCoolUI
.
async function testMyCoolUI() {
await uiFramework.openMyApp(url);
await sleep(2000);
startPollingForPopup(); // this is an async function, but not waiting on it
await uiFramework.clickButtonX();
await uiFramework.clickButtonY();
}
然而,这感觉是错误的,并且承诺将无法解决,并且该过程不会很好地清理。在 JS 中“正确”执行此操作的方法是什么?
其他想法:
Promise.all([testMyCoolUI, pollForPopup]);
但在这种情况下,测试仍将在轮询解决之前完成。出于同样的原因,这里并Promise.race
没有真正起作用。
解决方案
一个可以确保正确清理的良好代码结构模式是promise disposer 模式:
async function testMyCoolUI() {
await uiFramework.openMyApp(url);
await sleep(2000);
await withPollingForPopup(async () => {
await uiFramework.clickButtonX();
await uiFramework.clickButtonY();
});
}
async function withPollingForPopup(run) {
try {
startPollingForPopup(); // not waiting for anything
return await run();
} finally {
stopPollingForPopup(); // optionally `await` it
}
}
这假设有一个可以启动和停止的后台进程,可能是一个事件订阅。
或者,如果后台进程确实返回了一个拒绝错误的承诺并且您想尽快中止,您可以使用
async function withPollingForPopup(run) {
const poll = runPollingForPopup();
const [res] = await Promise.all([
run().finally(poll.stop),
poll.promise
]);
return res;
}
推荐阅读
- c# - C# UserControl 滚动条问题
- c++ - 提供多个值的 C++ 函数:引用参数还是元组?
- r - 如何计算序列坐标的向量和数据框之间的匹配?
- microservices - 开发人员是否应该能够在他们的开发环境中从 lerna monorepo 创建一个 docker 工件?
- java - 无法录制声音时,我的应用程序变得无响应
- scala - Actor系统默认分配了多少线程?
- javascript - 节点调度触发问题
- sql - 什么是透视这些数据的好方法?
- php - PHP $-SESSION 变量在新页面上消失并返回空
- ubuntu - /usr/bin/ld: 找不到 -lvtkGUISupportQt