在数组的排序函数中实现异步/等待javascript
我想在量角器ElementArrayFinder
上实现排序方法。众所周知,所有量角器方法都会返回承诺。 所以我的排序方法有一个条件,这取决于承诺解决方案。 我为了我使用async/await
节点插件,使其与node.js的版本低于6 (此处插件:https://www.npmjs.com/package/asyncawait)兼容在数组的排序函数中实现异步/等待javascript
这里我的代码,其中this
是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');
});
不幸的是,时间执行不是我所期望的。打印:array sorted
发生在比较x.localeCompare(y)
的打印之前。 任何想法我做错了什么?任何想法如何实现我的目标?
非常感谢您的帮助
sort
不采取异步回调。它期望一个数值作为返回值,而不是一个承诺;它确实返回一个数组而不是承诺。这是没有办法的(尽管可以实现一个自定义的异步排序算法 - 甚至是一个并行算法)。
但无论如何,这是非常低效的。在每个排序步骤中执行比较值的异步读取操作都会很慢 - 并且它会多次读取每个元素的相同值。不要这样做。相反,使用Schwartzian transform来获取要排序的值,然后进行排序(同步),然后使用结果。
你应该做
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');
这岂不是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飞溅.catch()
阶段需要?
嗨@Redu感谢您的回复。 是的,它确实支持V6中的ES6承诺,但我不记得自哪个版本节点支持es6承诺。 Btw使用量角器你应该使用他们的承诺本地实现:'protractor.promise' 我试图避免使用ES6承诺,即使比由量角器提供的标准更好 – quirimmo
Array.prototype.sort是一个同步函数。 – tibetty