栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

ES6之Promise详解

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ES6之Promise详解

前言

Promise,用于解决回调地域带来的问题,将异步操作以同步的操作编程表达出来,避免了层层嵌套的回调函数。

什么是 Promise

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

Promise特性
  • promise 对象代表一个异步操作,有三种状态:pending、fulfilled、reject
  • 任何其他状态都无法改变这个状态。这也是 Promise 这个名字的由来。'承诺’表示其他手段无法改变它的状态。
Promise 的出现解决什么问题

promise其实就是一个异步编程方案,在 promise 出现之前总会遇到所谓的’回掉地域’的嵌套代码

    step(1, function() {
 step(2, function() {
     step(3, function() {
  ……….
     })
 })
    })

都知道这种"回调地狱",是一种很让人恼火的代码书写格式,嵌套多层之后会让人阅读起来怀疑人生的。但是这种"回调地狱"真的就只有格式的问题嘛?显然不是。

引用例子

一个来自《YDKJS》的例子:一个程序员开发了一个付款的系统,它良好的运行了很长时间。突然有一天,一个客户在付款的时候信用卡被连续刷了五次。这名程序员在调查了以后发现,一个第三方的工具库因为某些原因把付款回调执行了五次。在与第三方团队沟通之后问题得到了解决。

上面的例子就是一个 信任问题 回调函数的方式会引发很多信任问题,例如重复调用,调用太晚等等问题。那么promise怎么解决上述两个问题的呢?

Promise意义
  • 可读性
    首先是 Promise 的 then 方法,支持我们在回调写在 then 方法中,让我们在日常开发中可以很清楚的看到,比如上面的代码就可以改写成
     Promise.resolve(1).
     .then(step => ++setp)
     .then(step => ++setp)
     .then(step => ++setp)
 ...
  • Promise 承诺的严谨性
    它与普通的回调方式的区别在于

普通方式,回调成功之后的操作直接写在了回调函数里面,而这些操作的调用是由第三方控制

Promise方式 回调只负责成功之后的通知,而回调成功之后的操作放在 then 的回调函数里面,由 Promise 精确控制。

注意 Promise 的状态不可逆。一旦发生改变就没有办法改变成任何一种状态。Promise 只能是异步的,所以不会出现异步的同步调用。

Promise缺点
  • 无法取消 Promise 一旦新建它就会立即执行,无法中途取消
  • 如果不设置回调函数,Promise 内部抛出的错误不会反应到外部。
  • 当处于 pending 状态,无法得知目前进行到哪一阶段(刚开始还是快结束)
如何使用Promise

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

Promise 构造函数接收一个函数作为参数,该函数的两个参数分别是 resolve 和 reject,这两个参数也函数,由 Javascript 提供,不需要自己添加

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。但一般不建议给then加两个参数,建议使用.then完成resolved状态的操作,使用.catch完成rejected的操作。
像这样:

    const promise = new Promise( (resolve,reject) => {
 resolve('ok');
 reject('error')
    })
    promise.then(res => {
 console.log(res)
    }).catch(err => {
 console.log(err)
    })

还可以用promise实现ajax的操作:

const getJSON = function(url){
 const promise = new Promise((resolve,reject) => {
     const handler = function(){
  if(this.readyState !== 4){//这两个if语句主要用来判断请求是否成功
      return;
  };
  if(this.status === 200){
      resolve(this.response)//这是成功请求后,将返回的数据传到回调函数中
  }else{
      reject(new Error(this.statusText))//这是失败后,将原因返给catch
  }
     };
     const xmlHttp = new XMLHttpRequest();//声明一个XMLHttpRequest对象的实例
     xmlHttp.open("get", url);//设置要发送的方法和地址
     xmlHttp.onreadystatechange = handler;//在这里调用上面定义的handler
     xmlHttp.responseType = "json";
     xmlHttp.setRequestHeader("Accept", "application/json");//设置请求头,规定接受json类型的数据
     xmlHttp.send();//真正的发送请求
 });
 return promise;
    };
    getJSON("url").then( res => {
 //成功后的操作
    }).catch(err => {
 //失败后的提示
    })

Promise可以嵌套使用,就是将一个Promise实例作为另一个Promise实例的resolve方法的参数传入。

说说then方法,这个方法是定义在Promise的原型上的,then方法返回的是一个新的Promise实例,因此可以采用链式写法,即then方法后面调用另一个then方法。

再来说几个Promise常用的api吧!

Promise.prototype.finally():

Finally方法用于不管promise对象的最后状态如何,都会执行的操作

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

Promise.resolve():

  • 这个方法用来将参数转变成Promise对象
  • 参数是一个Promise实例:不改动
  • 参数是一个thenable对象:会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
  • 参数不是具有then方法的对象,或根本就不是对象:返回一个新的Promise对象,状态为resolved
  • 不带有任何参数:直接返回一个ersolved状态的Promise对象

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

Promise.all():

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

用于将多个Promise实例,包装成一个新的Promise实例。这个方法接收一个数组作为参数,且都是Promise实例,如果不是,就会先调用Promise.resolve方法。
注意:
只有当数组中的实例的状态都是fulfilled,p才会变成fulfilled,此时,p1,p2,p3的返回值组成一个数组,传递给p的回调函数。
只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race():
和all方法类似,也是讲多个Promise实例包装成一个。
但不一样的是,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

在实际开发中,我们总希望让同步函数同步执行,异步函数异步执行,但如果同步函数想用Promise来做处理,能否实现同步呢?答案是肯定的。
这就要说到**Promise.try()**方法了

    const f = () => console.log('now');
    Promise.try(f);
    console.log('next');
// now// next

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号