本文首发于知乎专栏——前端面试题汇总,大家可以通过文章底部的阅读原来来访问原文地址
Promise是面试中经常遇到的,如果面试中面试官问你Promise.all()
怎么用,那你面试的岗位可能是差不多高级前端开发的岗位,但如果让你手写一个Promise.all()
那你面试的岗位应该就是资深/专家前端开发的岗位了
上期我们实现了函数的call()
、bind()
、apply()
方法。
Promise.all(iterable)
方法返回一个 Promise
实例,此实例在 iterable
参数内所有的 promise
都“完成(resolved)”或参数中不包含 promise
时回调完成(resolve);如果参数中 promise
有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise
的结果。
例子如下:
直接上代码:
核心思路:
Promise.myAll()
返回的肯定是一个promise
对象,所以可以直接写一个return new Promise((resolve, reject) => {})
(这应该是一个惯性思维)Promise.resolve()
将参数"包一层",使其变成一个promise
对象resolve
出来,在这里做了计数器(count
),每个内部promise对象决议后就将计数器加一,并判断加一后的大小是否与传入对象的数量相等,如果相等则调用resolve()
,如果任何一个promise对象失败,则调用reject()
方法。一些细节:
可遍历的
参数,所以未必一定是一个数组,所以用Array.from()
转化一下for…of
进行遍历,因为凡是可遍历的
变量应该都是部署了iterator
方法,所以用for…of
遍历最安全有了Promise.all()
的铺垫,race就好写多了。
核心思路:
finally()
方法返回一个Promise
。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise
是否成功完成后都需要执行的代码提供了一种方式。
这避免了同样的语句需要在then()
和catch()
中各写一次的情况。
核心思路:
this
指向的是当前Promise
对象,所以可以直接用this.then()
一些细节:
callback传入的有可能仍然是一个Promsie对象,如果真的是Promise对象,要等该promise决议之后才能执行之后then()方法,但是这个then()中拿到的是finally()之前的决议值,有种"决议值穿透"的感觉。
PS:我在网上找到了最权威的写法,毫无破绽 https://github.com/matthew-andrews/Promise.prototype.finally/blob/master/finally.js