解决异步编程的方案--重点promise

一、先来谈谈解决异步编程的方案

1.回调函数

ajax(url, () => {
    // 处理逻辑
    ajax(url1, () => {
        // 处理逻辑
        ajax(url2, () => {
            // 处理逻辑
        })
    })
})

在这里插入图片描述

回调函数的优点是简单、容易理解和实现,缺点是易造成回调地狱,不利于代码的阅读和维护,各个部分之间高度耦合,使得程序结构混乱、流程难以追踪(尤其是多个回调函数嵌套的情况),而且每个任务只能指定一个回调函数。此外它不能使用 try catch 捕获错误,不能直接 return。

2.事件监听(setTimeout)

 function f1() {
  setTimeout(function () {
    // ...
    f1.trigger('done');
  }, 1000);
}

上面代码中,f1.trigger(‘done’)表示,执行完成后,立即触发done事件,从而开始执行f2。
这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合",有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。阅读代码的时候,很难看出主流程。
在这里插入图片描述

3.发布/订阅(观察者模式)
在这里插入图片描述

这种方法的性质与“事件监听”类似,但是明显优于后者。因为可以通过查看“消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

4.Promise对象【es6】
5.async函数【es7】

二、什么是promise?

简单来说主要用于异步计算.

三、分析promise

  1. 简单的promise
    在这里插入图片描述

返回promise对象
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
图上报错可以忽略,promise捕捉reject状态默认失败报的错,可以用如下方式解决【使用全局捕捉并返回该状态】
在这里插入图片描述
2.简单应用
在这里插入图片描述
在这里插入图片描述
fn()执行成功之后才打印3,如果返回失败则往下执行
在这里插入图片描述
在这里插入图片描述

function fn(){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      console.log(2)
      reject("fail")
    },0)
  })
}
function main(){
  console.log(1)
  fn().then(()=>{

    console.log(3)
  })
}
main()
console.log(4)

3.promise对象的特点

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

4.实现原理(为什么会出现promise)

有没有遇到过这种需求,一个请求完毕后才能发起另一个请求。这样的话另一个请求就要嵌套进前一个请求中了,一个两个还好,但想象下要是有四五个呢,那代码将会变得非常难看和难以维护(回调地狱)。而promise的出现正是要解决这个问题的。

Promise 也还是使用回调函数,只不过是把回调封装在了内部,使用上一直通过 then 方法的链式调用,使得多层的回调嵌套看起来变成了同一层的

5.链式调用

在 then 中新创建的 Promise,它的状态变为 fulfilled 的节点是在上一个 Promise的回调执行完毕的时候。也就是说当一个 Promise 的状态被 fulfilled 之后,会执行其回调函数,而回调函数返回的结果会被当作 value,返回给下一个 Promise(也就是then 中产生的 Promise),同时下一个 Promise的状态也会被改变(执行 resolve 或 reject),然后再去执行其回调,以此类推下去…链式调用的效应就出来了。

真正的链式Promise是指在当前promise达到fulfilled状态后,即开始进行下一个promise.

四、分析async函数

1.什么是async函数
在这里插入图片描述
在这里插入图片描述

2.简单应用
await 后面跟的是 promise
在这里插入图片描述
在这里插入图片描述

五、为什么要使用异步

可以获取到成功或失败的状态然后在进行操作

六、用Promise对象实现 Ajax 操作

const getJSON = function(url) {
  const promise = new Promise(function(resolve, reject){
    const handler = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39490750/article/details/113939121