You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LazyMan('Tony');// Hi I am TonyLazyMan('Tony').sleep(10).eat('lunch');// Hi I am Tony// 等待了10秒...// I am eating lunchLazyMan('Tony').eat('lunch').sleep(10).eat('dinner');// Hi I am Tony// I am eating lunch// 等待了10秒...// I am eating dinerLazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');// Hi I am Tony// 等待了5秒...// I am eating lunch// I am eating dinner// 等待了10秒...// I am eating junk food
网上有很多 Promise 实现方式,看了都不是特别理解。
这里以一种更简单的形式一步一步去理解/实现它。这里仅涉及 Promise 构造函数和 then 方法的实现
首先构造一个最基本的 Promise 类
.then(onFulfilled)
为何需要用一个数组存放?then 方法可以调用多次,注册的多个onFulfilled,并且这些 onFulfilled callbacks 会在异步操作完成(执行resolve)后根据添加的顺序依次执行
异步执行处理 setTimeout vs status
上面 Promise 的实现存在一个问题:如果传入的 executor 不是一个异步函数,resolve直接同步执行,这时 callbacks 还是空数组, 导致后面 then 方法注册的 onFulfilled 回调就不会执行(resolve 比 then 注册先执行)
我们知道 then 中的回调总是通过异步执行的,我们可以在 resolve 中加入 setTimeout,将 callbacks 的执行时机放置到JS消息队列,这样 then方法的 onFulfilled 会先完成注册,再执行消息队列的 resolve
但是这样仍然有问题,如果我们延迟给 then 注册回调,这些回调也都无法执行。因为
还是 resolve 先执行完了,之后注册的回调就无法执行了。
可以看出 setTimeout 是无法保证 then 注册的 onFulfilled 正确执行的,所以这里必须加入状态机制(pending、fulfilled、rejected),且状态只能由 pending 转换为解决或拒绝。
当增加了状态后,setTimeout 就可以去掉了,状态机制让注册的回调总是能正确工作。
then的链式调用
链式调用我们可能很直接想到 then 方法中返回 this,这样 Promise 实例就可以多次调用 then 方法,但因为是同一个实例,调用再多次 then 也只能返回相同的一个结果。而我们希望的链式调用应该是这样的:
每个 then 注册的 onFulfilled 都返回不同结果,并把结果传给下一个 onFulfilled 的参数,所以 then 需要返回一个新的 Promise 实例
这样一个 Promise 就基本实现了,我们可以看到:
处理返回 Promise 类型的回调
这里还有一种特殊的情况:
这时我们只需用
res instanceof Promise
判断处理下拓展练习(面试题)
尝试实现下面函数
LazyMan
的功能参考答案from Daily-Interview-Question
The text was updated successfully, but these errors were encountered: