问题
I am trying to implement a sort method on protractor ElementArrayFinder
. As known, all protractor methods return promises.
So my sort method has a condition which depends on promises resolution.
I am using a node plugin for async/await
in order to make it compatible with node.js versions lower than 6.
(Here the plugin: https://www.npmjs.com/package/asyncawait)
Here my code, where this
is the ArrayElementFinder
:
var asyncCompare = async(function(a, b) {
let x = await (a.getText());
let y = await (b.getText());
console.log(x.localeCompare(y));
return x.localeCompare(y);
});
var sortTheArray = async(function(arrayOfElementFinders) {
return await (arrayOfElementFinders.sort(asyncCompare));
});
this.then((elements) => {
let arrayOfElementFinders = [elements[0], elements[1], elements[2]];
let sortedArray = sortTheArray(arrayOfElementFinders);
console.log('array sorted');
});
Unfortunately the timing execution is not the one I expect. The print: array sorted
happens before than the prints of comparing x.localeCompare(y)
.
Any idea what am I doing wrong? And any idea how to achieve my objective?
Thanks a lot for any help
回答1:
sort does not take an asynchronous callback. It expects a numeric value as the return value, not a promise for one; and it does return an array not a promise. There's no way around this (though one could implement a custom asynchronous sorting algorithm - even a parallel one).
But that's pretty inefficient anyway. Doing asynchronous fetching of compare values in every sort step will be slow - and it will fetch the same value per element multiple times. Don't do that. Instead, use a Schwartzian transform to fetch the values to sort by before, then sort (synchronously), then use the results.
You should do
const elements = await this;
const arrayOfElementFinders = elements.slice(0, 3); // or Array.from?
const comparableArray = await Promise.all(arrayOfElementFinders.map(async x => [await x.getText(), x]));
comparableArray.sort((a, b) => +(a[0] > b[0]) || -(a[0] < b[0]));
const sortedArray = comparableArray.map(x => x[1]);
console.log('array sorted');
回答2:
Does it not support promises before V6?
I dislike mixing imperative await
with functional promise
abstraction. Wouldn't you be able to do like?
Promise.all([Promise.resolve(10), Promise.resolve(4), Promise.resolve(7)])
.then(r => r.sort((a,b) => a-b))
.then(s => console.log(s));
ans splatter .catch()
stages as needed?
来源:https://stackoverflow.com/questions/45661247/implement-async-await-in-sort-function-of-arrays-javascript