If you want to omit calling then(d => d.method())
everytime, you could wrap your async calls in a small helper function:
const buy = {
cart: [],
apple: async function() {
setTimeout(() => {
this.cart.push('apple');
console.log(this.cart);
}, 1000);
return this;
}
};
function chain(object, ...asyncMethods) {
const methods = [...asyncMethods];
methods.reduce((acc, curr) => {
// if object is not a promise (first iteration), call the method
if (!acc.then) {
const promise = curr.call(acc);
return promise;
} else {
// if object is a promise, resolve it, then call the method
return acc.then((d) => curr.call(d));
}
}, object);
}
chain(buy, buy.apple, buy.apple, buy.apple);
// ['apple']
// ['apple', 'apple']
// ['apple', 'apple', 'apple']
However, this won't work if you have to pass arguments to your method. In that case, you could pass the function calls as objects like {buy: "orange"}
, then destructure them in your helper.
await
expression to chain functions. – Moriartyawait myAsyncFunction().then(x => x.somethingElse())
:-) – Mailbagasync/await
is not part of ES7. – YoungstownfindElement
returns a specialWebElementPromise
and not a regular Promise, which can be chained with fields and it will eventually return the result/returned value from the chained property/function (When it's a Promise, you can add await before everything, therefore this:await driver.findElement(By.css("button")).click();
is valid, and it's not needed toawait (await driver.findElement(By.css("button"))).click();
) – Immoderacy