Promise

  • Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大。
  • ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
  • ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

Promise 的用途

promise是为解决异步处理回调金字塔问题而产生的
她得特点是:

  1. Promise对象的状态不受外界影响
    1)pending 初始状态
    2)fulfilled 成功状态
    3)rejected 失败状态
    Promise 有以上三种状态,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态

  2. Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected

如何创建一个 new Promise

   return new Promise((resolve,reject)=>{})

一丶Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

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

二丶resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
三丶Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

   promise.then(function(value) {
         // success
       }, function(error) {
         // failure
       });
  • then方法可以接受两个回调函数作为参数。
    第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

如何使用 Promise.prototype.then

  • 由于 then 和 Promise.prototype.catch() 方法都会返回 promise,它们可以被链式调用——这同时也是一种被称为复合( composition) 的操作。

     var p1 = new Promise((resolve, reject) => {
       resolve('成功!');
       // or
       // reject(new Error("出错了!"));
     });
    
     p1.then(value => {
       console.log(value); // 成功!
     }, reason => {
       console.error(reason); // 出错了!
     });
    

如何使用 Promise.all

  • Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
    具体代码如下:

     let p1 = new Promise((resolve, reject) => {
       resolve('成功了')
     })
    
     let p2 = new Promise((resolve, reject) => {
       resolve('success')
     })
    
     let p3 = Promse.reject('失败')
    
     Promise.all([p1, p2]).then((result) => {
       console.log(result)               //['成功了', 'success']
     }).catch((error) => {
       console.log(error)
     })
    
     Promise.all([p1,p3,p2]).then((result) => {
       console.log(result)
     }).catch((error) => {
       console.log(error)      // 失败了,打出 '失败'
     })
    
  • Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。

代码模拟:

   let wake = (time) => {
   return new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(`${time / 1000}秒后醒来`)
       }, time)
     })
   }

   let p1 = wake(3000)
   let p2 = wake(2000)

   Promise.all([p1, p2]).then((result) => {
     console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
   }).catch((error) => {
     console.log(error)
   })       
  • 需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。
  • 这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

如何使用 Promise.race

  • 顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

    let p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('success')
      },1000)
    })
    
    let p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        reject('failed')
      }, 500)
    })
    
    Promise.race([p1, p2]).then((result) => {
      console.log(result)
    }).catch((error) => {
      console.log(error)  // 打开的是 'failed'
    })
    
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • //本文内容起初摘抄于 阮一峰 作者的译文,用于记录和学习,建议观者移步于原文 概念: 所谓的Promise,...
    曾经过往阅读 4,997评论 0 7
  • 1. Promise 的含义 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个...
    ROBIN2015阅读 3,477评论 0 0
  • Promise 的含义 一句话概括一下promise的作用:可以将异步操作以同步操作的流程表达出来,避免了层层嵌套...
    雪萌萌萌阅读 10,869评论 0 7
  • 前言 本文旨在简单讲解一下javascript中的Promise对象的概念,特性与简单的使用方法。并在文末会附上一...
    _暮雨清秋_阅读 6,621评论 0 3
  • Promise 是异步编程的一种解决方案,比传统的解决方案 —— 回调函数和事件 —— 更合理且强大 Promis...
    了凡和纤风阅读 3,477评论 0 1