ES6学习day07:Promise对象

Promise和async都是用于异步操作的方法,async在异步操作方面比Promise更加方便,语法更加易于理解。

1.Promise基本用法

  1. Promise为异步操作提供统一的接口,充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口。

  2. Promise可以让异步操作写起来就像写同步操作的流程,而不必一层一层的写嵌套函数。

  3. Promise是一个对象,也是一个构造函数,用来生成Promise实例。如下:

    //Promise是一个对象,也是一个构造函数,可以直接使用new运算符
    function fun1(resolve,reject){
    	//异步代码
    	setTimeout(function(){
    		console.log('成功执行1234');
    	},1000);
    }
    //无需调用就输出成功执行1234
    var promise1 = new Promise(fun1);//'成功执行1234'
    

    上面代码,Promise构造函数接受一个回调函数fun1作为参数,fun1里是异步操作的代码(这里每隔1秒执行一次),然后返回的promise1就是一个Promise实例。

    函数fun1中传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。

  4. Promise实例有一个then方法,用来指定下一步的回调函数。如下:

    var promise1 = new Promise(fun1);//'成功执行1234'
    promise1.then(fun2);
    

    上面的代码中,fun1的异步代码执行完后,就会执行fun2。传统写法可能需要把fun2作为回调函数传入fun1,比如:fun1(fun2),异步操作完成后,在fun1内部调用fun2。

    而Promise使得fun1和fun2变成了链式写法,对于多层嵌套的回调函数特别的方便,可读性好。

  5. Promise的设计思想

    • Promise的设计思想:所有异步任务都返回一个Promise实例。

    • 用法:

      (new Promise(fun1)).then(fun2)
      				.then(fun3)
      				.then(fun4);
      

2.Promise对象的状态

Promise对象通过自身的状态来控制异步操作。

Promise实例有三种状态:

  • 1.异步操作方法未完成(pending)

  • 2.异步操作成功(fulfiled)

  • 3.异步操作失败(rejected)

三种状态的变化途径只有两种:从"未完成"到"完成",从"未完成"到"失败"。fulfiled和rejected合一起称为resolved(已定型)。

Promise实例的变态变化只可能发生一次,因此Promise的最终结果只有两种的某一个:
1.异步操作成功:Promise实例传回一个值(value),状态变为fulfiled。
2.异步操作失败:Promise实例抛出一个错误(error),状态变化为rejected。

3.then()方法

  1. then方法用法和解释

    Promise实例的then方法,用来添加回调函数。

    then方法可以接受两个回调函数,第一个是异步操作成功时(变为fulfiled状态)的回调函数;第二个是异步操作失败(变为rejected)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。

    例如:

    //then方法绑定两个回调函数console.log和console.error
    var promise1 = new Promise(function fun1(resolve,reject){
    	resolve('successful')
    });
    
    promise1.then(console.log,console.error);//successful
    
    var promise2 = new Promise(function fun1(resolve,reject){
    	reject('failed')
    });
    
    promise2.then(console.log,console.error);//failed
    

    输出结果:
    在这里插入图片描述

    resolve和reject是两个函数,她们由JavaScript引擎提供,不用自己实现。

    上面代码:then方法绑定两个回调函数:成功时的回调函数console.log和失败时的回调函数console.error(可省略)。

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

  2. then方法的链式操作

    如下:
    在这里插入图片描述
    最后一个then方法,回调函数是console.log和console.error,console.log只显示step3的返回值,而console.error可以显示P1、step1、step2、step3之中任意一个发生的错误。

    若step1的状态变为rejected,那么step2和step3就不会执行了(因为它们是resolve的回调函数)。Promise开始寻找接下开第一个rejected的回调函数,在上面的代码中是console.error,因此Promise对象的报错具有传递性。

  3. Promise的then中只能传递函数,如果为其他类型,例如另一Promise,会被解释为null,此时Promsie的值传递会穿透

    如:
    在这里插入图片描述

    Promise.resolve('foo')
    .then(Promise.resolve('bar'))
    .then(function(result){
        console.log(result);
    });//foo
    //会被解释为:
    Promise.resolve('foo')
    .then(null)
    .then(function(result){
        console.log(result);
    });//foo
    

4.promise的catch方法

一般来说,不要在then方法里面定义 reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

// bad
promise.then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。

跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应!!!

一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法!!!

上述部分引自阮一峰老师的《ECMAScript 6 入门》

5.promise的执行顺序

秘诀:promise的异步代码是从then函数开始的。

有如下代码:

let promise = new Promise(function(resolve, reject) {
  console.log('hello');
  resolve();
});

promise.then(function() {
  console.log('异步resolved.');
});

console.log('Hi!');

// hello
// Hi!
// 异步resolved

输出结果为:
在这里插入图片描述
上述部分引自阮一峰老师的《ECMAScript 6 入门》

在这里插入图片描述

时光太美,每天进步一点点,开心一点点!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值