Protractor中Promise处理及控制流相关技术疑问咨询
Great question—this is one of the most common pain points when learning Protractor, since its promise handling feels different from regular JavaScript. Let’s break this down step by step:
Do you always need .then() after Protractor calls?
No, you don’t—and that’s all thanks to Protractor’s built-in Control Flow mechanism.
The Control Flow acts like a queue for all your Protractor/WebDriver commands. When you write consecutive Protractor calls (like .clear() followed by .sendKeys()), the Control Flow automatically waits for the previous promise to resolve before executing the next one. It handles all the promise chaining behind the scenes, so you don’t have to wrap every command in .then().
Is getFieldX().clear().sendKeys('abc'); valid?
Absolutely! This works perfectly because the Control Flow will ensure .clear() finishes before .sendKeys('abc') runs.
You only need to use .then() here if you want to run non-Protractor code after .clear() completes. For example:
getFieldX().clear().then(() => { console.log("Field has been cleared!"); // Regular JS code that needs to wait for clear() getFieldX().sendKeys('abc'); // Even this can stay in the then, but the Control Flow still manages it });
Without .then(), that console.log would run immediately (before .clear() finishes), since it’s not a Protractor command and the Control Flow doesn’t track regular JavaScript.
Why do some examples use .then() and others don’t?
It boils down to what you’re doing after the promise resolves:
- No
.then()needed: When you’re just chaining Protractor/WebDriver commands (like.click()→.sendKeys()), the Control Flow handles the ordering automatically. .then()required: When you need to:- Access the resolved value of a promise (e.g., getting text from an element with
.getText().then(text => console.log(text))) - Run regular JavaScript code that depends on the promise completing (like logging, updating local variables, or conditional logic)
- Break out of the Control Flow to do something outside of Protractor’s command queue
- Access the resolved value of a promise (e.g., getting text from an element with
Does the Control Flow only work in specs?
Yes, mostly. The Control Flow is tightly integrated with Jasmine’s test lifecycle—it only activates within your it blocks (specs) and the Jasmine hooks like beforeEach/afterEach.
If you write a regular function outside of a spec and call Protractor commands inside it:
- If you call that function from within a spec, the Control Flow will still manage the commands (since it’s running in the spec’s context).
- If you call it outside of any spec, the Control Flow won’t be active, and you’ll need to handle promises manually (either with
.then()or by usingasync/await).
A quick note: Modern Protractor versions recommend using async/await instead of the Control Flow, as it’s more intuitive and aligns with standard JavaScript async patterns. For example:
async function fillField() { const field = getFieldX(); await field.clear(); await field.sendKeys('abc'); }
This removes the need to rely on the Control Flow entirely, making your code easier to debug and read.
内容的提问来源于stack exchange,提问作者GarfieldKlon

