我试图了解如何(以什么顺序)在 Protractor 中执行 promise ,特别是对于与 Protractor promise 混合的非 Protractor promise (例如 native 或 q promise )。 我在工作中调试和修复一些不稳定的 Protractor 测试,我绝对不是 JavaScript 程序员;因此,在给出答案时,假设你的答案会超出我的理解范围,并将其降低一两个级别。
在经历了几天运气不佳的特殊测试后,我决定编写一些非常简单的示例来尝试理解 promise 链是如何执行的。 根据我在网上阅读的内容,我认为这样链接:
a().then(() => {
x();
b().then(() => {
y();
c().then(() => z());
});
});
应该是一样的:
a().then(() => {
x();
b();
}).then(() => {
y();
c();
}).then(() => z());
这也应该与此相同(如果我在工作中使用的是 ES6,但我不是):
await a();
await x();
await b();
await y();
await c();
await z();
你可以在这里看到我的完整代码以及我得到的输出: https://github.com/cpjust/TypeScriptTest/tree/dev/specs
对于所有这些场景以及使用原生 promise 与 Protractor promise 时,我都得到了不同的结果。 在 second_spec.ts 中,我还尝试在应该失败的 promises 中添加 expect() 语句,我期望在 expect() 之后链接的 promises 不会执行,因为 expect 应该抛出断言错误,但我看到的是promises 在它执行后,但由于 expect() 失败,测试仍然失败。很奇怪...
最佳答案
您的一个问题包含许多子问题,但都很好。所以最好一一进行,我会尽力解释这可能会帮助您解决问题。
first_spec.ts
it('promise chain 1', function () {
/* Prints the following:
[TRACE] default - Start
[DEBUG] default - Sleeping for 100 ms...
[TRACE] default - End
[INFO] default - --1
[DEBUG] default - Sleeping for 200 ms...
[INFO] default - --2
[DEBUG] default - Sleeping for 300 ms...
[INFO] default - --3
[INFO] default - --done
*/
logger.trace("Start");
printLater("--1", 100).then(() => {
printLater("--2", 200).then(() => {
printLater("--3", 300).thenFinally(() => {
logger.info("--done");
});
});
});
logger.trace("End");
});
这个非常简单。 printLater 返回 promise browser.sleep,所以它必须等待给定的时间然后让它解析。这意味着每个 printLater 都必须在进入下一个之前完成。我希望你不要怀疑这个 it block 。
it(' promise 链 1.1', function () { /* 打印以下内容: [TRACE] 默认 - 开始 [DEBUG] 默认 - 休眠 100 毫秒...... [TRACE] 默认 - 结束 [信息] 默认 - --1 */ logger.trace("开始");
nativePromise("--1", 100).then(() => { nativePromise("--2", 200).then(() => { nativePromise("--3", 300).finally(() => { logger.info("--done"); }); }); }); logger.trace("End"); });
在这种情况下,nativePromise 创建 Promise 对象并在其中调用 printLater。让我解释一下流程是如何发生的。 当我们调用函数 nativePromise 时,它直接返回当前处于默认挂起状态的 promise 对象(因为任何 promise 对象都有三种状态 resolve/reject/pending)。现在在 nativePromise 上使用 then 期望 resolve/reject 状态但它仍然处于挂起状态无限期直到测试超时。这就是测试在某一点发生并且不做任何事情的原因。最后一点是,由于异步行为,我们为第一个 nativePromise 获得了一些输出。因为有 printLater 函数异步工作并记录其结果。
使它与第一个 it block 相同的简单方法是对 nativePromise 函数进行轻微更改。您将必须使用 resolve 来确保此 promise 得到解决。
function nativePromise(msg, time) {
return new Promise((resolve) => {
resolve(printLater(msg, time));
});
}
注意:解决/拒绝 promise 始终是最佳实践。
it('await promise 3.1', async function () {
/* Prints the following:
[TRACE] default - Start
[DEBUG] default - Sleeping for 100 ms...
[INFO] default - --1
*/
await logger.trace("Start");
await nativePromise("--1", 100);
await nativePromise("--2", 200); // Gets stuck after "--1"
await nativePromise("--3", 300);
await logger.info("--done");
await logger.trace("End");
});
对于前面的代码片段,原因与我之前提到的相同。 await 也等待解决/拒绝的 promise 。如果它没有返回任何东西,那么 await 也会卡在某一点。
我们使用 await 来使代码更简洁。在内部它也等待 promise 解决/拒绝并且它不返回 promise 对象。 await 从 promise 对象中取出值并返回。
注意 1:Jasmine 的期望在执行任何进一步操作之前等待控制流为空 refer this link from Protractor
注意 2:Protractor Promise 实际上是 webdriver。Promise 在 Protractor 和 webdriverJs 中被弃用。所以如果可能的话不要使用它们。
关于javascript - 我如何将 expect() 与 Protractor promise 链中的非 Protractor promise 混合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56641077/