发现这个问题在数组javascript的排序函数中实现async/await,但我的是不同的。
我想实现异步版本的排序函数。我的编程语言编译成JavaScript,叫做Gaiman,默认情况下一切都是异步的。这使得代码更加简单。有些事情可以是真正异步的,比如从用户那里读取输入,但是Gaiman中定义的所有函数都是异步的,即使它们没有使用任何真正异步的东西。
我已经实现了自定义类扩展Array:
function is_function(obj) {
return typeof obj === 'function';
}
function is_promise(obj) {
return obj && is_function(obj.then);
}
class GaimanArray extends Array {
map(...args) {
function call(arr) {
return new GaimanArray(...arr);
}
const arr = super.map.apply(this, args);
const some = super.some;
const has_promise = some.call(arr, is_promise);
if (has_promise) {
return Promise.all(arr).then(call);
} else {
return call(arr);
}
}
forEach(...args) {
return this.map(...args);
}
filter(fn, ctx) {
const filter = super.filter;
function call(arr) {
return new GaimanArray(...filter.call(arr, x => x));
}
const items = this.map(fn, ctx);
if (is_promise(items)) {
return items.then(arr => {
return call(arr);
});
} else {
return call(items);
}
}
reduce(fn, init) {
return super.reduce.call(this, function(acc, ...args) {
if (is_promise(acc)) {
return acc.then(acc => {
return fn(acc, ...args);
});
} else {
return fn(acc, ...args);
}
}, init);
}
sort() {
}
some(fn, ctx) {
const some = super.some;
return this.mapWithCallback(fn, (arr) => {
return some.call(arr, x => x);
}, ctx);
}
every(fn, ctx) {
const every = super.every;
return this.mapWithCallback(fn, (arr) => {
return every.call(arr, x => x);
}, ctx);
}
find(fn, ctx) {
return this.mapWithCallback(fn, (arr) => {
const index = arr.findIndex(x => x);
return this[index];
}, ctx);
}
flatMap(fn, ...args) {
return this.map(...args).flat();
}
mapWithCallback(fn, callback, ctx) {
const items = this.map(fn, ctx);
if (is_promise(items)) {
return items.then(arr => {
return callback(arr);
});
} else {
return callback(items);
}
}
}
方法的实现在我的数组实际上使基于承诺的函数可选,这是一个剩余的实现当我修改数组。原型,但它给一些其他库执行args.some(is_promise)
的问题。
我认为我不能使用施瓦茨变换,因为我不能得到每一项的值,我的比较函数需要真正的异步。
那么我如何在JavaScript中实现异步排序?每个方法都与异步函数一起工作,除了我不知道如何实现排序。
我已经创建了基于rossetta code的工作代码:
// based on: https://rosettacode.org/wiki/Sorting_algorithms/Merge_sort#JavaScript
async function mergeSort(array, fn) {
if (array.length <= 1) {
return array;
}
const mid = Math.floor(array.length / 2),
left = array.slice(0, mid), right = array.slice(mid);
await mergeSort(left, fn);
await mergeSort(right, fn);
let ia = 0, il = 0, ir = 0;
while (il < left.length && ir < right.length) {
array[ia++] = (await fn(left[il], right[ir]) <= 0) ? left[il++] : right[ir++];
}
while (il < left.length) {
array[ia++] = left[il++];
}
while (ir < right.length) {
array[ia++] = right[ir++];
}
return array;
}