-
Notifications
You must be signed in to change notification settings - Fork 239
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
This turns out to be the most annoying new API to implement in quite a while. There are numerous polyfills out there but they're all broken in subtle or often not so subtle ways.
After much trial and error, I put together a polyfill that passes all test262 tests except for one (Array.fromAsync.prototype should not exist but you can't fix that from JS) and believe me when I say you cannot change or remove a single line without breaking some tests.
;(function() {
"use strict" // result.length=i should throw if .length is not writable
const {Array, Object, Symbol} = globalThis
const {asyncIterator, iterator} = Symbol
Object.defineProperty(Array, "fromAsync", {value:fromAsync, configurable:true, writable:true})
async function fromAsync(arrayLike, mapFn=undefined, thisArg=undefined) {
if (mapFn !== undefined && typeof mapFn !== "function") throw new TypeError("not a function")
let result, i = 0, isConstructor = typeof this === "function"
let sync = false, method = arrayLike[asyncIterator]
if (method == null) sync = true, method = arrayLike[iterator]
if (method == null) {
let {length} = arrayLike
length = +length || 0
result = isConstructor ? new this(length) : Array(length)
while (i < length) {
let value = arrayLike[i]
if (sync) value = await value
if (mapFn) value = await mapFn.call(thisArg, value, i)
Object.defineProperty(result, i++, {value, configurable: true, writable: true})
}
} else {
const iter = method.call(arrayLike)
result = isConstructor ? new this() : Array()
try {
for (;;) {
let {value, done} = await iter.next()
if (done) break
if (sync) value = await value
if (mapFn) value = await mapFn.call(thisArg, value, i)
Object.defineProperty(result, i++, {value, configurable: true, writable: true})
}
} finally {
if (iter.return) iter.return()
}
}
result.length = i
return result
}
})()Now to translate that to C. All those await expressions are going to be a massive pain.
It might actually be an interesting experiment to write complex built-ins in JS and compile to bytecode ahead of time, a la qjsc.
saghul
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request