Promise的基本使用

网络请求的回调地狱

我们来考虑下面的场景(有夸张的成分):

我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2

我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3

我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4

发送网络请求url4,获取最终的数据data4

image.png

上面的代码有什么问题吗?

正常情况下,不会有什么问题,可以正常运行并且获取我们想要的结果。

但是,这样代码难看而且不容易维护。

我们更加期望的是一种更加优雅的方式来进行这种异步操作。

如何做呢?就是使用Promise。

Promise可以以一种非常优雅的方式来解决这个问题。

promise的基本使用

使用setTimeOut模拟网络请求

//第一次网络请求
setTimeout(()=>{
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
          //第二次网络请求
           setTimeout(()=>{
               console.log('hello world');
               console.log('hello world');
               console.log('hello world');
               console.log('hello world');
           },1000)
         //第三次网络请求
           setTimeout(()=>{
               console.log('hello world');
               console.log('hello world');
               console.log('hello world');
               console.log('hello world');
           },1000)
  },1000)

这样的代码难看,可以使用Promise

 new Promise((resolve, reject)=>{

           //第一次网路请求
           setTimeout(()=>{
               resolve();
           },1000)
       }).then(data => {
           //第一次拿到结果的处理代码
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           return new Promise((resolve, reject)=>{
               //第二次网路请求
               setTimeout(()=>{
                   resolve();
               },1000)
           },1000)
       }).then(data => {
           //第二次拿到结果的处理代码
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           return new Promise((resolve, reject)=>{
               //第三次网路请求
               setTimeout(()=>{
                   resolve();
               },1000)
           },1000)
       }).then(data => {
           //第三次拿到结果的处理代码
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
           console.log('hello world');
       })

使用promise链式调用,代码更加清晰

Promise三种状态

首先, 当我们开发中有异步操作时, 就可以给异步操作包装一个Promise

异步操作之后会有三种状态

我们一起来看一下这三种状态:

pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。

fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()

reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()

image.png
image.png

链式调用简写

       new Promise((resolve, reject)=>{
           setTimeout(()=>{
               resolve('aaa');
           },1000)
       }).then(data => {
           console.log(data,'第一层的10行处理代码');
           return new Promise((resolve, reject)=>{
               setTimeout(()=>{
                   resolve(data + '111');
               },1000)
           },1000)
       }).then(data => {
           console.log(data,'第二层的10行处理代码');
       })

return new Promise((resolve, reject)=>可以简写为 promise.resolve,promise.reject
简写为:

     new Promise((resolve, reject)=>{
           setTimeout(()=>{
               resolve('aaa');
           },1000)
       }).then(data => {
           console.log(data,'第一层的10行处理代码');
           return Promise.resolve(data + '111');
       }).then(data => {
           console.log(data,'第二层的10行处理代码');
       })

还可以再次简写:return Promise.resovle(data)简写为return data

new Promise((resolve, reject)=>{
           setTimeout(()=>{
               resolve('aaa');
           },1000)
       }).then(data => {
           console.log(data,'第一层的10行处理代码');
           return data + '111';
       }).then(data => {
           console.log(data,'第二层的10行处理代码');
       })

all的用法

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调

 Promise.all([
           //操作1
           new Promise((resolve, reject)=>{
               setTimeout(()=>{
                   resolve('result1');
               },1000)
           }),
           //操作2
           new Promise((resolve, reject)=>{
               setTimeout(()=>{
                   resolve('result2');
               },1000)
           }),
       ]).then(results =>{
            console.log(results);
  })

操作1、操作2执行完才会调用then


参考:
https://www.jiagou1216.com/life/front/801.html
https://www.cnblogs.com/lvdabao/p/jquery-deferred.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容