Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
810 views
in Technique[技术] by (71.8m points)

sorting - Implement async/await in sort function of arrays javascript

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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');

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...