-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Description
谢谢你的文章,受益匪浅😁。以下是我发现的一些问题:
[1] Promise.all
根据 mdn 文档,Promise.all() 方法接收一个 promise 的 iterable 类型。
用 Array.isArray 来判断感觉不是很对,用 iterable?.[Symbol.iterator] == null 或许会更合适一些。
在这个基础上,使用 length 来判断迭代的个数就会出现错误了。Set 跟 Map 是没有 length 属性的。
且也不能用 forEach 来遍历,因为如果传入 string 类型会报错。
这样写的话应该好一些:
Promise.all = function (iterable) {
if (iterable?.[Symbol.iterator] == null) {
throw new TypeError(
`${iterable} is not iterable (cannot read property Symbol(Symbol.iterator))`,
)
}
return new Promise((resolve, reject) => {
let index = 0
let count = 0
const result = []
const length =
(iterable instanceof Set || iterable instanceof Map) ? iterable.size : iterable.length
if (length === 0) {
resolve([])
}
for (const item of iterable) {
if (item instanceof Promise) {
;(index => {
Promise.resolve(item).then(
value => {
result[index] = value
count += 1
count === length && resolve(result)
},
reason => {
reject(reason)
},
)
})(index)
} else {
result[index] = item
count += 1
count === length && resolve(result)
}
index += 1
}
})
}同理,接收可迭代对象的 promise 方法都应该改一下参数校验的方式。
[2] Promise.resolve
当传入包含 then 方法的对象时,执行的顺序可能会与原生的 promise 有区别。比如
console.log(
Promise.resolve({
then() {
console.log(1)
},
}),
)以上代码,原生 promise 会先打印 promise,再打印 1,而手写的会先打印 1,再打印 promise。
且应该先判断 then 方法是否为一个函数。如果不是的话,会返回整个对象。
[3] Promise.any
errors.push(reason); 会导致 errors 数组的顺序不可控,与原生的 Promise.any 方法有出入。
Metadata
Metadata
Assignees
Labels
No labels