异步函数调用的变迁

83 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

Promise.png

回调地狱时代

在ajax流行的时期,想必大家都知道一个ajax请求里边,在嵌套另外一个ajax请求。

 function getList() {
   // ...
   var XHR = new XMLHttpRequest();
   XHR.open('GET', url, true);
   XHR.send();
 ​
   XHR.onreadystatechange = function() {
       if (XHR.readyState == 4 && XHR.status == 200) {
           result = XHR.response;
           console.log(result);// 拿到了结果
          // 现在在发一个请求
       }
   }
 }

这只是简单的发请求获取数据,还没有加上业务逻辑在里边,可以想想如果再把业务逻辑放在里边,后期的维护成本就高的不行了。

一个函数做一件事情

那就把复杂的逻辑,都单另出来,封装自己的业务逻辑。

 // 一个简单的封装
 function want() {
     console.log('这是你想要执行的代码');
 }
 ​
 function fn(want) {
     console.log('这里表示执行了一大堆各种代码');
 ​
     // 其他代码执行完毕,最后执行回调函数
     want && want();
 }
 ​
 fn(want);

但还是解决不了我们回调地狱的问题。只不过是看起来清晰了。

Promise登场

三种状态

  1. pending: 等待中,或者进行中,表示还没有得到结果
  2. resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行
  3. rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行
 new Promise(function(resolve, reject) {
     if(true) { resolve() };
     if(false) { reject() };
 })

then方法

接收两个参数,一个是成功的回调,一个是失败的回调

 function fn(num) {
     return new Promise(function(resolve, reject) {
         if (typeof num == 'number') {
             resolve();
         } else {
             reject();
         }
     }).then(function() {
         console.log('参数是一个number值');
     }, function() {
         console.log('参数不是一个number值');
     })
 }
 ​
 fn('hahha');
 fn(1234);

Promise.all

将多个 Promise 实例,包装成一个新的 Promise 实例

 const p = Promise.all([p1, p2, p3]);

p的状态由p1p2p3决定,分成两种情况。

  1. (1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。
  2. (2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

aysnc/await

Generator 函数的语法糖

 const asyncReadFile = async function () {
   const f1 = await readFile('/etc/fstab');
   const f2 = await readFile('/etc/shells');
   console.log(f1.toString());
   console.log(f2.toString());
 };

总结

回调地狱的出现,让人头疼,不好维护。紧接着出现了Promise,使用链式调用的方式,解决了回调地狱的问题;同时还有一个就是满屏的then操作,不好看;紧接着出现了async/await。他们是Gennerator的语法糖。将异步的函数整成了同步的写法。让人一幕了然。