美文网首页
javascript中的神器 ---- Promise

javascript中的神器 ---- Promise

作者: 那年点夏 | 来源:发表于2018-12-31 16:27 被阅读0次

    为何用Promise?

    我们平时不怎么会遇到回调嵌套很多层的情况,一般也就是一到二级,但是如果遇到回调嵌套很多时,代码层面看会很繁琐,这种情况我们一般称----回调地狱。极端情况如下图:


    badCallBack

    由此,Promise的概念最早由社区提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。作用与回调方法几乎一致,都是在某种情况下执行预先设定好的方法,但是使用它却能够让代码变得更简洁清晰。

    什么是Promise?

    复杂的概念我们先不讲,我们先直观的看一下promise是个什么东西呢?这时候我们直接在控制台打印出来看一下吧:console.dir(Promise):


    Promise

    我们一看结果就可以看出来,Promise本身是一个构造函数,它自身和原型上都提供了几个api。
    Promise翻译过来是表示“承诺”:承诺将来会执行。
    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

    基本用法

    下面代码创造了一个Promise实例。

    const promise = new Promise((resolve, reject)=> {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    

    Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
    resolve函数的作用是,将状态由“未完成”变为“成功”,将异步成功操作的结果,作为参数传递出去;
    reject函数的作用是,将状态由“未完成”变为“失败”,将异步错误操作的结果,作为参数传递出去;

    Promise实例的常用方法

    Promise.resolve()

    Promise.resolve()旨在将现有对象转换成Promise对象。
    Promise.resolve等价于下面的写法。

    Promise.resolve('foo')
    // 等价于
    new Promise(resolve => resolve('foo'))
    

    Promise.reject()

    Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

    const p = Promise.reject('出错了');
    // 等同于
    const p = new Promise((resolve, reject) => reject('出错了'))
    
    p.then(null, function (s) {
      console.log(s)
    });
    // 出错了
    

    上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。

    Promise.prototype.then()

    Promise实例具有then方法,从我们上面console的结果可以看出,then是定义在原型对象Promise.prototype上的;它的作用是为 Promise 实例添加状态改变时的回调函数。
    then方法可以接受两个回调函数作为参数,第一个参数是成功的回调,第二个参数是失败的回调,其中,第二个参数是可选的。这两个函数都接受Promise对象传出的值作为参数。可以由上面生成的promise实例来简单举个例子:

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

    then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

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

    Promise.prototype.catch()

    Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
    一般都会使用catch来捕获promise的错误回调结果,但是最好不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

    // bad
    promise
      .then((data)=> {
        // success
      },(err)=> {
        // error
      });
    
    // good
    promise
      .then((data)=> { //cb
        // success
      })
      .catch((err)=> {
        // error
      });
    

    Promise.prototype.all()

    Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    const p = Promise.all([p1, p2, p3]);
    

    上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

    Promise.prototype.finally()

    finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

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

    上面代码中,不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
    finally本质上是then方法的特例。

    相关文章

      网友评论

          本文标题:javascript中的神器 ---- Promise

          本文链接:https://www.haomeiwen.com/subject/nlmilqtx.html