天天看点

ES6——Promise函数一、三个状态二、基本用法三、then()四、Promise.all()五、Promise.race()六、Promise.resolve()七、Promise.reject()八、Generator 函数与 Promise 的结合

文章目录

  • 一、三个状态
  • 二、基本用法
    • 1.举例
    • 2.使用原生Ajax
    • 3.图片异步加载(懒加载)
  • 三、then()
  • 四、Promise.all()
  • 五、Promise.race()
  • 六、Promise.resolve()
  • 七、Promise.reject()
  • 八、Generator 函数与 Promise 的结合

异步编程解决方案

一、三个状态

1.promise内部状态 不受外界影响,由异步编程结果决定

pending进行中

fulfilled成功

rejected失败

2.promise中的状态 一旦发生变化不会再修改

Promise对象的状态改变,只有两种可能:

从pending变为fulfilled 和 从pending变为rejected

二、基本用法

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,它们是两个函数

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去

1.举例

let promise=new Promise((resolve,reject)=>{
        let status=true;
        if(status){
            resolve('成功');
        }
        else{
            reject(new Error('失败'));
        }
    })

    //promise对象的使用
    //写法一
    promise.then((res)=>{
        //成功回调函数 resolve
        console.log(res);
    },(error)=>{
        console.log(error);
    })
    //输出:   成功

	//写法二
	    promise.then((res)=>{
        //resolve
        console.log(res);
    }).catch(()=>{
        //reject
        console.log(error);
    }).finally(()=>{
        console.log("最终执行的代码");
    });
    //输出:  成功 最终执行的代码
           

2.使用原生Ajax

function Ajax(method,url,data,callback){
        var http;
        if(window.XMLHttpRequest){
            http=new XMLHttpRequest();
        }
        else{
            //IE5,IE6
            http=new ActiveXObject("Microsoft.XMLHTTP");
        }
        if(method=="get"){
            if(data){
                url+="?";
                url+=data;
            }
            http.open(method,url);
            http.send();
        }
        else{
            http.open(method,url);
            if(data){
                http.send(data);
            }
            else{
                http.send();
            }
        }
        http.onreadystatechange= function () {
            if(http.readyState==4&&http.status==200){
                //匿名函数回调 才能把数据拿到外面使用
                callback(http.response);
            }
        }
    }
    
    let promise=new Promise((resolve,reject)=>{
        try{
            Ajax('get','./city.json',null,(res)=>{
                resolve(res);
            });
        }
        catch(e){
            reject(e);
        }
    })

    promise.then((res)=>{
     //resolve
     	console.log(res);
     }).catch(()=>{
     //reject
     	console.log(error);
     }).finally(()=>{
     	console.log("最终执行的代码");
     });
           
ES6——Promise函数一、三个状态二、基本用法三、then()四、Promise.all()五、Promise.race()六、Promise.resolve()七、Promise.reject()八、Generator 函数与 Promise 的结合

(上面内容即为city.json的全部内容)

3.图片异步加载(懒加载)

异步加载要比同步加载快很多

let promise= function (src) {
        return new Promise(function (resolve,reject) {
            let image=new Image();
            image.onload= function () {
                resolve(this); //即image
            }
            image.onerror= function () {
                reject(new Error("图片加载失败"));
            }
            image.src=src;   //相当于给浏览器缓存了一张图片
        })
    }
    
    let src='./1.jpg'
    promise(src).then((img)=>{
        console.log(img);
        document.body.appendChild(img);
    }).catch((error)=>{
        console.log(error);
    })
           
ES6——Promise函数一、三个状态二、基本用法三、then()四、Promise.all()五、Promise.race()六、Promise.resolve()七、Promise.reject()八、Generator 函数与 Promise 的结合

三、then()

1.then方法定义在原型对象Promise.prototype上

ES6——Promise函数一、三个状态二、基本用法三、then()四、Promise.all()五、Promise.race()六、Promise.resolve()七、Promise.reject()八、Generator 函数与 Promise 的结合

2.then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。

因此可以采用链式写法,即then方法后面再调用另一个then方法。

let promise=new Promise(function (resolve,reject) {
        let data={
            json: function () {
                return {id:1};
            }
        }
        if(data){
            resolve(data);
        }
        else{
            reject(new Error("出错了"));
        }
    })
    promise.then(function (res) {
//        console.log(res);  //{json: ƒ}
        return res.json();
    }).then(function (res) {
        console.log(res);  //{id: 1}
    })
           

四、Promise.all()

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

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

let p1=new Promise((resolve,rejecr)=>{
        resolve(1);
    });
    let p2=new Promise((resolve,rejecr)=>{
        resolve(2);
    })
    let p=Promise.all([p1,p2]);
    p.then((result)=>{
        console.log(result);   // [1, 2]
    })
           
let p1=new Promise((resolve,rejecr)=>{
        resolve(1);
    });
    let p2=new Promise((resolve,rejecr)=>{
        reject(new Error("失败"));
    })
    let p=Promise.all([p1,p2]);
    p.then((result)=>{
        console.log(result); 
    }).catch((err)=>{
        console.log(err);  //Error: 失败
    })
           

五、Promise.race()

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

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。

那个率先改变的 Promise 实例的返回值,就传递给p的回调函数

let p1=new Promise((resolve,reject)=>{
        //模拟请求 5000ms请求回来的数据
        setTimeout(function () {
            resolve("数据");
        },5000);
    });
    let p2=new Promise((resolve,reject)=>{
        //模拟请求 2s后按超时处理
        setTimeout(function () {
            reject(new Error("超时"));
        },2000);
    });
    let p=Promise.race([p1,p2]);
    p.then((res)=>{
        console.log(res);
    }).catch((err)=>{
        console.log(err);
    });
           

两秒后,p2状态先改变:

ES6——Promise函数一、三个状态二、基本用法三、then()四、Promise.all()五、Promise.race()六、Promise.resolve()七、Promise.reject()八、Generator 函数与 Promise 的结合

六、Promise.resolve()

将现有对象转为一个新的 Promise 对象

Promise.resolve(12);
    //等价
    new Promise(resolve=>resolve(12));
           

(1)如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

(2)参数是一个thenable对象(即如果转化对象存在then方法)

会默认执行自身的then方法

let obj={
        then: function (resolve) {
            resolve(22);
        }
    }
    let p=Promise.resolve(obj);
    p.then(function (res) {
        console.log(res); //22
    })
           

(3)不是thenable对象

let obj={id:1};
    let p=Promise.resolve(obj);
    p.then(function (res) {
        console.log(res);  //{id: 1}
    })
           

七、Promise.reject()

也会返回一个新的 Promise 实例,该实例的状态为rejected

Promise.reject(new Error("失败"));
//等价
new Promise((resolve,reject)=>reject(new Error("失败")))
           

八、Generator 函数与 Promise 的结合

使用 Generator 函数管理流程,遇到异步操作的时候,通常返回一个Promise对象

let p= function () {
        return new Promise(function (resolve) {
            setTimeout(function () {
                resolve("数据");
            },3000)
        })
    }
    let gen= function* (){
        try{
            let res=yield p();
            console.log(res);
        }catch(e){
            throw e.message;
        }
    }
    function run(Generator){
        let it=Generator(); //返回遍历器

        function go(result){
            if(result.done){
                return result.value;
            }
            return result.value.then(function (res) {
            	//console.log(res);  //数据
                return go(it.next(res));
            }).catch(function (err) {
                it.throw(err);
            })
        }
        go(it.next());
    }
    run(gen);
    //三秒后输出: 数据
           
es6