Promise介绍和使用

Promise

Promise是一门新的技术(ES6规范),JS中进行异步编程的新解决方案。(旧的方案是使用回调函数,比如AJAX请求)。
从语法上来说Promise是一个构造函数。
从功能上来说Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值。

Promise初体验

<script>
    //普通实现异步方法setTimeout()
    const btn = document.querySelector('#btn');
    btn.addEventListener('click',()=>{
        setTimeout(()=>{
            alert('1秒后执行');
        },1000);
    });
    
    document.querySelector('#btn1').addEventListener('click',()=>{
        //使用Promise
        //1. resolve 函数类型数据,异步执行成功回调
        //2. reject 函数类型数据,异步执行失败回调
        const promise = new Promise((resolve,reject)=>{
            setTimeout(()=>{
                //获取1-10的随机数
                let n = Math.floor(Math.random() * (10 - 1 + 1)) + 1;
                if(n <= 5){
                    resolve(n); //将promise对象状态设置为 成功
                    console.log('resolve');
                }else{
                    reject(n);//将promise对象状态设置为 失败
                    console.log('resolve');
                }
            },1000);
        });
        //调用then方法获取异步函数执行状态,执行的是resolve/reject
        //接受两个函数 resolve & reject
        promise.then((val)=>{
            alert('resolve ' + val);
        },(val)=>{
            alert('reject ' + val);
        });
    });
    
</script>

catch方法

const promise = new Promise((resolve,reject)=>{
            //获取1-10的随机数
            let n = Math.floor(Math.random() * (10 - 1 + 1)) + 1;
            if(n<=5){
                resolve(n);
            }else{
                reject(n);
            }
        }).then((val)=>{
            console.log('success' + val);
        }).catch((err)=>{
            console.log('failure' + err);
        });

使用Promise封装AJAX请求

  const btn = document.querySelector('#btn');
    btn.addEventListener('click',()=>{
        const promise = sendAJAX('http://localhost/test');
         //调用then方法
        promise.then((val)=>{
            //成功
            console.log(val);
        },(val)=>{
            //失败
            console.log(val);
        });
    });

    function sendAJAX(url){
        const promise = new Promise((resolve,reject)=>{
            //1. AJAX请求 , 创建http客户端
            const http = new XMLHttpRequest();
            //2. 初始化
            http.open('GET',url);
            //3. 发送请求
            http.send();
            //4. 处理响应结果
            http.onreadystatechange = function(){
            if(http.readyState === 4){
                if(http.status == 200){
                    //成功
                    resolve(http.response);
                }else{
                    //失败
                    reject(http.status);
                }
            }
            }
       });
       return promise;
    }

Promise属性

PromiseState:Promise状态

  1. pending:等待,初始化默认值
  2. resolved / fullfilled:表示成功
  3. rejected:表示失败

PromiseResult:保存着对象的结果。成功/失败

  1. resolve():resolve方法会把状态改为成功,并且存成功的结果
  2. reject():reject方法会把状态改为失败,并且保存失败结果

Promise方法

  1. Promise.resolve()方法:如果传入的参数是非Promise类型的对象,则返回结果是成功的Promise对象,如果传入的参数为Promise对象,则参数的结果决定了resolve的结果
    let promise = Promise.resolve(1);
        console.log(promise);
        promise = Promise.resolve(new Promise((resolve,reject)=>{
            //resolve();
            reject();
        }));
        console.log(promise);
    
  2. Promise.reject()方法:快速的返回一个失败的Promise对象,无论传入什么,返回结果都是失败。
    let promise = Promise.reject(1)
    console.log(promise);
    
  3. Promise.all()方法:传入Promise数组,只有所有的Promise对象都成功才成功,只要有一个失败就直接失败。成功的返回结果是全部的Promise对象。无论有多少个失败,都会执行完全部的Promise。
      const p1 = new Promise((resolve,reject)=>{
            resolve();
            console.log(1)
        })
        const p2 = new Promise((resolve,reject)=>{
            reject();
            console.log(2)
        })
        const p3 = new Promise((resolve,reject)=>{
            reject();
            console.log(3)
        })
        let promises = Promise.all([p1,p2,p3])
        console.log(promises);
    
  4. Promise.race()方法:传入Promise数组,第一个完成的Promise的结果的状态就是最终的结果状态。结果也是第一个成功返回的结果。
      const p1 = new Promise((resolve,reject)=>{
            resolve();
            console.log(1)
        })
        const p2 = new Promise((resolve,reject)=>{
            reject();
            console.log(2)
        })
        const p3 = new Promise((resolve,reject)=>{
            reject();
            console.log(3)
        })
        let promises = Promise.race([p1,p2,p3])
        console.log(promises);
    

Promise关键知识

  1. 如何改变Promise状态
    const promise = new Promise((resolve,reject)=>{
          //1. 调用resolve()方法,改为成功状态
          resolve();
          //2. 调用reject()方法,改为失败状态
          reject();
          //3. 抛出一个异常改为失败状态 throw
          throw 'has error';
        })
    
  2. 可以为Promise指定多个then函数,都会被执行
      const promise = new Promise((resolve,reject)=>{
          resolve();
        }).then(()=>{
            console.log(1);
        }).then(()=>{
            console.log(2);
        }).then(()=>{
            console.log(3);
        });
    
  3. then和catch函数,是执行器里执行reslove()或者reject()方法才会执行
    const promise = new Promise((resolve,reject)=>{
          setTimeout(()=>{
            console.log('setTimeout');
            resolve();
          },2000)
        }).then(()=>{
            console.log(1);
        }).then(()=>{
            console.log(2);
        }).then(()=>{
            console.log(3);
        });
    

Promise链式调用

Promise的then方法可以返回Promise对象,当返回Promise对象时,后续的then方法接受到的参数是上一个then返回Promise返回的对象的返回值,如下。
也就是说,可以实现对异步操作的链式调用,只用上一个异步执行接受,有返回值的时候才会执行下一个then,不需要自己去判断线程的状态。

 //三个异步方法,最后输出为 1 2 3
 const promise = new Promise((resolve,reject)=>{
          //1. 第一个异步方法
          setTimeout(()=>{
            resolve(1);
          },2000)
        }).then((val)=>{
            console.log(val);
            return new Promise((resolve,reject)=>{
                //2. 第二个异步方法
                setTimeout(()=>{
                    resolve(2);
                },1000)
            })
        }).then((val)=>{
            console.log(val);
            return new Promise((resolve,reject)=>{
                //3. 第三个异步方法
                setTimeout(()=>{
                    resolve(3);
                },1000)
            })
        }).then((val)=>{
            console.log(val);
        });

链式调用的异常穿透

链式调用过程中,只需要有一个catch,如果其中某一环节出错,抛出异常throw 'error msg',则会执行catch的函数,不会继续执行接下来的任务。

 const promise = new Promise((resolve,reject)=>{
          setTimeout(()=>{
            resolve(1);
          },2000)
        }).then((val)=>{
            console.log(val);
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    //抛出异常直接执行catch,不会执行继续执行,因为没有执行到resolve()方法
                    throw 'error';
                    resolve(2);
                   
                },1000)
            })
        }).then((val)=>{
            console.log(val);
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    resolve(3);
                },1000)
            })
        }).then((val)=>{
            console.log(val);
        }).catch(err=>{
            console.log(err);
        });

中断链式调用

  1. 中断链式调用的方法是返回一个空函数的Promise对象new Promise(()=>{})这样就不会跳入下一个then里面
  2. 在某些业务场景中可以抛出异常来中断Promise,如上异常穿透也是终止了链式调用。这种直接调用了catch,也属于另类的终止
 promise = new Promise((resolve,reject)=>{
          setTimeout(()=>{
            resolve(1);
          },2000)
        }).then((val)=>{
            console.log(val);
            //终止链式调用
            return new Promise(()=>{})
        }).then((val)=>{
            console.log(2);
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    resolve(3);
                },1000)
            })
        }).then((val)=>{
            console.log(val);
        }).catch(err=>{
            console.log(err);
        });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值