我试图了解如何在量角器中执行承诺(按什么顺序),特别是对于与量角器承诺混合的非量角器承诺(例如本机或q承诺)。 我正在调试和修复一些不稳定的量角器测试,而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
在所有这些情况下以及使用原生承诺与量角器承诺时,我都得到了不同的结果。 在second_spec.ts中,我还尝试在promise中添加Expect()语句,该语句应该失败,并且我期望在期望()之后链接的promise不会执行,因为期望会引发断言错误,但是我看到的是在执行之后发出诺言,但是由于Expect()失败,测试仍然失败。很奇怪...
答案 0 :(得分:0)
您的一个问题包含许多子问题,但都很好。因此,最好是一个一个地走,我会尽力向您解释这可能会帮助您解决问题。
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('promise chain 1.1',function(){ / *打印以下内容: [TRACE]默认-开始 [DEBUG]默认-睡眠100毫秒... [TRACE]默认-结束 [INFO]默认--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函数可以异步工作并记录其结果。
使其与first it块相同的简单方法是对nativePromise函数进行一些更改。您将必须使用resolve来确保此诺言得以解决。
function nativePromise(msg, time) {
return new Promise((resolve) => {
resolve(printLater(msg, time));
});
}
注意:解决/拒绝诺言始终是最佳实践。
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解析/拒绝,并且不返回promise对象。等待从promise对象获取值并返回。
注意1:Jasmine的期望在执行任何进一步的操作refer this link from Protractor
之前等待控制流为空。注2:Protractor Promise实际上是webdriver.Promise在Protractor和webdriverJs中已弃用。因此,如果可能不要使用它们。