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
functionstep(){console.log("wait for about 3 seconds...");setTimeout(()=>{red();setTimeout(()=>{green();setTimeout(()=>{yellow();step();},2000);},1000);},3000);}step();
第二版:封装定时器
varlight=(timmer,cb)=>{setTimeout(()=>{cb();},timmer);};functionstep(cb){light(3000,()=>{red();light(1000,()=>{green();light(2000,()=>{yellow();step();});});});typeofcb==="function"&&cb();}step(()=>console.log("wait for about 3 seconds..."));
Promise 定义
总结一下回调函数的情况:
对于这些情况,可能都要在回调函数中做些处理,并且每次执行回调函数的时候都要做些处理,这就带来了很多重复的代码。
回调地狱的其他问题:
Promise 使得以上绝大部分的问题都得到了解决。
使用第三方回调 API 的时候,可能会遇到如下问题:
对于第一个问题,Promise 只能 resolve 一次,剩下的调用都会被忽略。
对于第二个问题,我们可以使用 Promise.race 函数来解决。
对于第三个问题,即使 promise 对象立刻进入 resolved 状态,即同步调用 resolve 函数,then 函数中指定的方法依然是异步进行的。
PromiseA+ 规范也有明确的规定:
Promise 的局限性:
其实这并不是 Promise 独有的局限性,try catch 也是这样,同样会捕获一个异常并简单的吃掉错误。
而正是因为错误被吃掉,Promise 链中的错误很容易被忽略掉,这也是为什么会一般推荐在 Promise 链的最后添加一个 catch 函数,因为对于一个没有错误处理函数的 Promise 链,任何错误都会在链中被传播下去,直到你注册了错误处理函数。
Promise 只能有一个完成值或一个拒绝原因,当需要传递多个值时,构造成一个对象或数组,然后再传递,then 中获得这个值后,又会进行取值赋值的操作。使用 ES6 的解构赋值:
Promise 一旦新建它就会立即执行,无法中途取消。
当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
异步处理的几种方式
先定义下红绿灯:
异步编程的语法目标,就是怎样让它更像同步编程,有以下几种:
一、回调函数
这是最常见的一种方式,把函数作为参数送入,然后回调。
第一版:简单明了
第二版:封装定时器
二、事件监听
采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
第一版:监听一个事件,然后触发这个事件,并且执行事件里的回调函数
第二版:加个顺序执行
依旧是回调执行,我们继续远征吧。
三、发布/订阅
订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Event Channel),当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
第一版:
第二版:
三、Promise
直接上代码:
四、Generator
Promise 的写法减少了好多回调,但是仍有回调的存在,这次尝试使用 Generator,看是否能够避免回调。
五、Async/await
有了 Generator 做铺垫,
async/await
就比较容易理解了:同步写法,容易理解,和我们的线性思考方式一致,
async/await
是ES2017
的方案。学习资料
The text was updated successfully, but these errors were encountered: