阅读 11

你就需要这篇文章,带你搞懂实战的 Promise 对象

----欢迎查看我的博客----

什么是promise对象

  promise的诞生,是为了解决回调地狱,相信这个词大家听的比较多了。简单说就是一个异步的方法完成后再触发方法,再触发下一个异步方法,再触发方法,再触发一个异步方法......周而复始,不停的callback,写法非常繁琐,因此es6中出现了promise对象。   它早已不是一个新名词。ES6中已经原生对它加以支持,但是低版本的浏览器我们可以使用es6-promise这个polyfill库来加以兼容。它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败。

image

ajax

  我们以ajax为例子,我们来看下传统的ajax和promise包裹住的ajax,有什么区别,分析出来您大概就明白了

普通ajax

getData(method, url, successFun, failFun){
  var xmlHttp = new XMLHttpRequest();
  xmlHttp.open(method, url);
  xmlHttp.send();
  xmlHttp.onload = function () {
    if (this.status == 200 ) {
      successFun(this.response);
    } else {
      failFun(this.statusText);
    }
  };
  xmlHttp.onerror = function () {
    failFun(this.statusText);
  };
}
getData('get','www.xxx.com',()=>{...},()=>{...})
复制代码

promise包裹的

getData(method, url){
    var promise = new Promise(function(resolve, reject){
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open(method, url);
    xmlHttp.send();
    xmlHttp.onload = function () {
      if (this.status == 200 ) {
        resolve(this.response);
      } else {
        reject(this.statusText);
      }
    };
    xmlHttp.onerror = function () {
      reject(this.statusText);
    };
  })
  return promise;
}

getData('get','www.xxx.com').then(...).catch(
    (err) => { console.log(err) }
)
复制代码

  看完上面两个例子,应该都知道promise是什么了吧。说白了只不过是换了种写法,其实本质还是一样的,所以大家没必要对新东西恐惧。其实就这样了。

Promise使用方法

  promise有这么几种方法,用来调用promise对象。

resolve()方法

  上面样例我们通过 resolve 方法把 Promise 的状态置为完成态,ajax200状态,这时 then 方法就能捕捉到变化,并执行“成功”情况的回调。

reject()方法

  而 reject 方法就是把 Promise 的状态置为已失败,这时 then 方法执行“失败”情况的回调。

then()方法

  简单来讲,then 方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。而 Promise 的优势就在于这个链式调用。我们可以在 then 方法中继续写 Promise 对象并返回,然后继续调用 then 来进行回调操作.这个就不多说了,上面代码有例子

catch()方法

  就是抛异常,promise通过reject方法失败后的方法通过catch的方法去抛异常抛出来。通过then的方法将他catch出来。其实非常简单,没什么可以讲的。

Promise.all()

  promise对象组成的数组作为参数,并返回一个新的promise对象。

function timeout(time) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(time);
        }, time);
    });
}
console.time('promise')
Promise.all([
    timeout(10),
    timeout(60),
    timeout(100)
]).then(function (values) {
    console.log(values); [10, 60, 100]
    console.timeEnd('promise');   // 101ms
});

复制代码

  由此我们可以看出,传入的多个对象几乎是同时执行的,因为总的时间略大于用时最长的一个对象resolve的时间。我理解的 是根据你的计算机配置来计算最多执行几个promise,这个就很有利用点了,比如多个promise对象,for循环同时执行,我们可以考虑将所有的promise对象组成一个promise数组,然后.all去完成大量的请求。非常有用。

race()方法

  race 按字面解释,就是赛跑的意思。race 的用法与 all 一样,只不过 all 是等所有异步操作都执行完毕后才执行 then 回调。而 race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调。我们来把all换成race方法。

function timeout(time) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(time);
        }, time);
    });
}
console.time('promise')
Promise.race([
    timeout(10),
    timeout(60),
    timeout(100)
]).then(function (values) {
    console.log(values); //10
    console.timeEnd('promise');   // 11.75ms
});

复制代码

  与Promise.all()不同,它是在数组中有一个对象(最早改变状态)resolve或reject时,就改变自身的状态,并执行响应的回调。

如何取消 promise

  在这篇文章中有提到这里就不多说了,请看这里 ajax 和 fetch 和 axios 的区别

结语

  好了今天的promise就讲到这里,如果更往深层次研究,坑肯定 还是有的,例如promise不能取消,后面我们有时间在详细说说这个玩意,好了不说了,困死我了今天,昨晚看人民的民义,我去硬是看完了大结局,精彩是精彩的,就是官二代有点多。。。哈哈哈,不说了拜拜

评论