Implement async/await in sort function of arrays javascript

旧巷老猫 提交于 2019-12-22 05:41:04

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!