ES6之Promise学习与实践

1.前言前端

  在平时的业务开发中,前端一般须要请求后台获取数据,或者NodeJs读取文件等等一系列的异步操做,咱们一般须要利用异步操做的结果或者对异步操做的结果进行处理。一般咱们的解决方案是:在异步操做成功或者失败的回调函数里面写方法,在异步操做比较简单的时候这样写代码仍是比较好理解的,当业务逐渐趋于复杂,这就造成了回调地狱,代码嵌套层数太多而且难以理解。不过,办法老是有的,可使用ES6的新特性Promise来解决问题。es6

2.Promise的定义编程

  Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最先提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。json

所谓Promise,简单说就是一个容器,里面保存着某个将来才会结束的事件(一般是一个异步操做)的结果。从语法上说,Promise 是一个对象,从它能够获取异步操做的消息。Promise 提供统一的 API,各类异步操做均可以用一样的方法进行处理。promise

Promise对象有如下两个特色。app

(1)对象的状态不受外界影响。Promise对象表明一个异步操做,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其余手段没法改变。ecmascript

(2)一旦状态改变,就不会再变,任什么时候候均可以获得这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种状况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。若是改变已经发生了,你再对Promise对象添加回调函数,也会当即获得这个结果。这与事件(Event)彻底不一样,事件的特色是,若是你错过了它,再去监听,是得不到结果的。异步

有了Promise对象,就能够将异步操做以同步操做的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操做更加容易。ide

Promise也有一些缺点。首先,没法取消Promise,一旦新建它就会当即执行,没法中途取消。其次,若是不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,没法得知目前进展到哪个阶段(刚刚开始仍是即将完成)。异步编程

3.基本用法

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

代码以下:

const promise=new Promise(function(resolve,reject){
  if(/* 异步操做成功*/){
    resolve(value)
  }else{
    reject(error);
  }
});

Promise构造函数接受一个函数做为参数,改函数的两个参数分别是resolve与reject,resolve函数的做用是:将Promsie对象的状态从“未完成”变为“成功”,在异步操做成功时回调,并将异步操做的结果value做为参数传递出去;reject函数的做用是:Promise对象的状态由“未完成”变为“失败”,在异步操做失败时调用,并将异步操做报出的错误做为参数传递出去。

Promise实例生成之后,能够用then方法分别制定resolved的状态和reject状态的回调函数。

代码以下:

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

4.小例子-封装Ajax操做

 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("./js/package.json").then(function(json) {
    console.log('Contents: ' , json);
  }, function(error) {
    console.error('出错了', error);
  });

以上的代码是经过用原生的Ajax和Promise实现的获取json的一个方法,在网页中运行得出如下的结果:

5.reject状态回调方法的写法

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

以上是咱们的reject状态方法,能够做为promsie对象then方法的第二个参数。不过这样写有个缺点是:若是在resolve状态以后再抛出错误,则不会捕获。

推荐写法:

// 推荐写法
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

  经过Promise这种写法,咱们使不少异步操做的方法写法同步化,可以更好的组织优化代码,并且在捕获错误也更加容易,方便咱们调试解决问题。不足之处,多多指正。


 

参考资料:

 《ECMAScript 6 入门》-阮一峰

《MDN-Promise》

相关文章
相关标签/搜索