在数组javascript的排序功能中实现异步/等待

新手上路,请多包涵

我正在尝试在量角器 ElementArrayFinder 上实现一种排序方法。众所周知,所有量角器方法都返回承诺。所以我的排序方法有一个条件取决于承诺的解决。我正在为 async/await 使用节点插件,以使其与低于 6 的 node.js 版本兼容。(这里是插件: https ://www.npmjs.com/package/asyncawait)

这是我的代码,其中 thisArrayElementFinder

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

不幸的是,计时执行不是我所期望的。打印: array sorted 发生在比较打印 x.localeCompare(y) 之前。知道我做错了什么吗?知道如何实现我的目标吗?

非常感谢您的帮助

原文由 quirimmo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 391
2 个回答

sort 不接受异步回调。它期望一个数值作为返回值,而不是一个承诺;它确实返回一个数组而不是一个承诺。没有办法解决这个问题(尽管可以实现自定义异步排序算法——甚至是并行排序算法)。

但无论如何,这是非常低效的。在每个排序步骤中异步获取比较值会很慢 - 并且它会多次获取每个元素的相同值。不要那样做。相反,使用 Schwartzian 变换 来获取要排序的值,然后(同步)排序,然后使用结果。

你应该做

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

原文由 Bergi 发布,翻译遵循 CC BY-SA 3.0 许可协议

它不支持V6之前的承诺吗?

我不喜欢混合命令式 await 与功能性 promise 抽象。你不能这样做吗?

 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() 根据需要分阶段?

原文由 Redu 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题