es62---promise异步编程

一.用promise对象处理异步

创建promise异步编程
resolve reject 回调函数
resolve 成功的时候回调函数
reject 失败的时候
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数(then括号里边写回调函数)

 	//首先要生成promise实例
    const promise = new Promise(function (resolve, reject) {
        if (true) {  //异步操作成功
            resolve("数据");  //resolve,reject是两个函数
        }
        else {
            reject("失败");
        }
    })
    //在外边获取异步数据
    promise.then(function (res) {
         console.log(res);
    }), function (error) {
         console.log(error);
    }

下边这种写法比较高级,只写了成功时候的的程序

 function timeout(ms) {
      return new Promise((resolve, reject) => {
            setTimeout(resolve, ms, 'done');
  	  });
  }

  timeout(100).then((value) => {
      console.log(value);
  });

settimeout的第三个参数
前面的回调函数的附加参数

    function show(){
        return setTimeout((a,b,c) => {
            console.log(a,b,c)
    }, 1000, "my", "name", "is starsion");
    }
    show();  //输出
    my name is starsion

一个promise 只能写一个请求
promise与抓异常语句一起使用
catch里边的参数,是new Error里边定义的异常信息
promise.then().catch() catch里边抛出异常信息

	let promise=new Promise(function (resolve,reject){
       try{
         	if(true){
         		setTimeout(resolve,100,1);
         	}
         	else{
         		throw new Error("数据请求异常!");
         	}
         }
        catch(err){
         	reject(err);
         }
    });
    promise.then(function (res){
         console.log(res);
    }).catch(function (err){
         console.log(err);
    });

promise对象的执行顺序

 	var data=null;
    var promise=new Promise(function(resolve){
        console.log("start");
        setTimeout(resolve,1000,"内部");
    });
    console.log("外部");
    promise.then(function(res){
        console.log(res);
        data=123;
    });
    console.log("end");
    console.log(data);  //null

“内部”会隔一秒再输出,data输出的是null(内部还没有执行完,data还没有赋上值,代码的异步执行)
在这里插入图片描述

二.promise 异步加载图片

浏览器性能优化

    var promise=new Promise(function(resolve,reject){
        var imges=new Image();
        imges.src="img/01.jpg";
        imges.onload=function(res){
            setTimeout(resolve,1000,imges);
        };
        imges.error=function(){
            reject(new Error("图片异常!"))
        }
    });
    promise.then(function(res){
        console.log(res);     //<img src="img/01.jpg">
    }),function(err){
        console.log(err);
    }

三.用promise对象实现AJAX操作

原生ajax的promise异步封装
onreadystatechange 读取事件的状态 里边判断readyState=4,status=200
responseType 数据类型

    const post = function (url, data) {
        const promise = new Promise(function (resolve, reject) {
            let http = new XMLHttpRequest();
            let handle = function () {
                if (http.readyState != 4) {
                    return;
                }
                if (http.status == 200) {
                    resolve(http.response);
                }
                else {
                    reject(new Error("请求数据失败!"));
                }
            }
            http.open("post", url);
            http.onreadystatechange = handle;
            http.responseType = "json";
            if (data) {
                http.send(data);
            }
            else {
                http.send();
            }
        });
        return promise;
    }
    //post里边是要传的数据
    post("./data/stu.json").then(function (res){
        console.log(res);
    }).catch(function(err){
        console.log(err);
    });

es6教程

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);
});

四.多个promise连用

promise2等待promise1结束

    var promise1=new Promise(function(resolve,reject){
        setTimeout(resolve,5000,"数据");
    })
    var promise2=new Promise(function(resolve,reject){
        setTimeout(resolve,1000,promise1);
    })
    promise2.then(function(res){
        console.log(res);
    })

    const p1 = new Promise(function (resolve, reject) {
        setTimeout(() => reject(new Error('fail')), 3000)
    })

    const p2 = new Promise(function (resolve, reject) {
        setTimeout(() => resolve(p1), 1000)
    })

    p2.then(result => console.log(result))        
    .catch(error => console.log(error))    // Error: fail 因为p1是输出错误信息,所以是catch这一行输出

五.promise原型的then,catch,finally方法

Promise.prototype.catch()
用于指定发生错误时的回调函数。
Promise.prototype.finally()
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
finally:操作服务器之后,可以在异步编程里边进行关闭,也可以等待数据在promise里边拿完之后在finally里边进行关闭,因为finally最后一定会执行。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
例子:服务器使用 Promise 处理请求,然后使用finally方法关掉服务器。

server.listen(port)
  .then(function () {
    // ...
  })
  .finally(server.stop);

Promise.prototype.then()
Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
constructor
构造函数就是new Promise()括号里边的回调函数
Promise.all()
Promise.all( )方法用于将多个 Promise 实例,包装成一个新的 Promise 实例

链式操作then方法里边必须写return,不然all里边拿不到

连着点的时候需要return

 	const p1=new Promise(function(resolve,reject){
        setTimeout(resolve,2000,"学生");
    })//.then(res=>res).catch(err=>err); 注释掉的也可以不写,最后也可以输出值

    const p2=new Promise(function(resolve,reject){
        setTimeout(resolve,4000,"老师");
    })//.then(res=>res).catch(err=>err);
    
    const p3=Promise.all([p1,p2]).then(res=>console.log(res)).catch(err=>console.log(err));

p3 p4 是一个新的promise 若什么都不写便没有promiseValue值,里边要写return 返回res

		 const p1 = new Promise(function (resolve, reject) {
         	setTimeout(resolve, 1000, "学生");
         });
         // p3  p4  是一个新的promise   没有promiseValue
         let p3=p1.then(function (res){
         	return res;    //若这里边没有这个return的话,promiseValue的值为undefined,想有value值,里边必须写return值
         });

         const p2 = new Promise(function (resolve, reject) {
         	setTimeout(resolve, 1000, "老师");
         });
         let p4=p2.then(function (res){
         		return res;
         });

         console.log(p3,p4);
         //合并
         const p5 = Promise.all([p1, p2]).then(function (res) {
         	console.log(res);
         }).catch(function (err) {
         	console.log(err);
         });

在这里插入图片描述
若第一个then不给第二个then 返回res,则第二个then新new的promise会没有参数,输出的会是undefined;

   const p = new Promise(function (resolve, reject) {
            setTimeout(resolve, 1000, "数据");
        }).then(function (res) {
                    console.log(res);  //数据
                    return res;
                }).then(function (res) {
                    console.log(res);  //若没有上一个return,输出为undefined;上一个return了之后输出的是数据
                    //第一个then出了一个新的promise,可是这个promise的promiseValue的值为空,必须return res给这个promiseValue赋值,下一个then才可以接收到值
                    return res;
                }).then(function (res) {
                    console.log(res);
                });

es6官方文档里边的案例

    const p1 = new Promise((resolve, reject) => {
                resolve('hello');
    }).then(result => result)
    .catch(e => e);

    const p2 = new Promise((resolve, reject) => {
                throw new Error('报错了');
    }).then(result => result)
    .catch(e => console.log(e));/*throw new出的错误,会在catch中报出*/

    Promise.all([p1, p2])
    .then(result => console.log(result))
    .catch(e => console.log(e));
    // ["hello", Error: 报错了]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值