[ES6] Promise

Promise

Promise是ES6提出解决异步编程的方案,相比于传统的回调函数,Promise更符合人们的编程习惯,也更强大。Promise是一个对象,通常会保存着异步操作的结果。
Promise有两大特点:

  • Promise的结果不受外界影响,只跟异步操作的结果有关。Promise对象代表一个异步操作,有三种状态:pending、fulfilled和rejected。
  • Promise一旦发生状态改变,则不会再发生变化。也就是从pending变成fulfilled或rejected之后就再也不会发生变化了。

Promise的优点:

  • 不用再写地狱回调了,将异步操作用同步的方法表示出来。
  • Promise提供了统一的API,可以比较方便的控制异步操作。

Promise的缺点:

  • Promise一旦开始执行就无法中途取消。
  • Promise无法得知内部的执行情况,无法得知异步是刚开始执行还是已经快执行结束了,也无法捕捉内部抛出的异常。

Promise的语法

Promise对象是一个构造函数,用来生成Promise实例。Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。

const promise = new Promise (function (resolve,reject){
  var img = document.createElement('img');
  img.onload = function(){
    resolve(img);
  }
  img.onerror = function(){
    reject();
  }
  img.src = src;
})

resolve函数的作用是,将Promise对象的状态从 pending 变为 resolved,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,将Promise对象的状态从 pending 变为 rejected,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成后,可以使用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(img){
   console.log(img.width) //sucess
},function(){
  console.log('failed') //failed
})

接下来举个例子,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。

function loadImg(src){
      const promise = new Promise (function (resolve,reject){
          var img = document.createElement('img')
          img.onload = function(){
              resolve(img)
          }
          img.onerror = function(){
              reject()
          }
          img.src = src
      })
      return promise  //一定要return
  }
  var src = 'https://www.baidu.com/static/img/index/logo_new.png'
  var result = loadImg(src)
  result.then(function(img){
      console.log(img.width)
  },function(){
      console.log('failed')
  })

如果调用resolve或reject函数时带有参数,那么它们的参数会被传递给回调函数。reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还有可能是其他的 Promise 实例。

const promise1 = new Promise(function (resolve, reject) {
  // ...
});

const promise2 = new Promise(function (resolve, reject) {
  // ...
  resolve(promise1); //promise2异步操作的结果是返回promise1异步操作的结果
})

通常来说,调用resolve或reject以后,Promise 就应该完成了,接下来的操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,建议在它们前面加上return语句,这样就不会去执行后面的语句了。

new Promise((resolve, reject) => {
  return resolve(1); //建议加上return
  // 后面的语句不会执行
  console.log(2);
})

then

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

你可能感兴趣的:([ES6] Promise)