zoukankan      html  css  js  c++  java
  • ES6 --- Promise

    概述

    概念上说,Promise是异步编程的一种解决方案。

    从语法上说,Promise是一个对象,可以从他获取异步操作的消息。

    状态

    Promise对象有三种状态:

    1. pending (进行中)

    2. fulfilled(已成功)

    3. rejected (已失败)

      > 特点

      Promise对象有两个特点:

      1. 对象的状态不受外界印象。Promise对象的状态只有异步操作的结果可以决定

      2. 对象的状态改变就不会再变。Promise对象有两种状态改变,一是从pending到resolved,二是从pending到rejected。这两种状态只要发生一种,就会一直保持这个结果。

      > 缺点

      1. Promise一旦执行,无法取消。

      2. Promise如果不设置回调函数,其内部抛出的错误不会反应到外部

      3. pending状态,无法得知目前进展到哪一个阶段

    参数

    Promise接受一个函数作为参数,这个函数的两个参数分别是resolve和reject。

    1. resolve -> 将Promise对象的状态从pending变为resolved,并且将异步操作成功返回的结果作为参数传递出去

    2. reject -> 将Promise对象的状态从pending变为 rejected,并且将异步操作返回的错t误作为参数传递出去

    then方法

    then方法接收两个函数作为参数,第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数。两个函数只有一个会被调用。

     1 let p  = new Promise((resolve,reject) => {
     2     resolve() 
     3 })
     4 p.then(() => {
     5     console.log("then方法的第一个参数")
     6 },() => {
     7     console.log("then方法的第二个参数")
     8 })
     9 .catch(() => {
    10     console.log("catch方法")
    11 })

    结果输出: 

      then方法的第一个参数

     1 let p  = new Promise((resolve,reject) => {
     2     reject()
     3 })
     4 p.then(() => {
     5     console.log("then方法的第一个参数")
     6 },() => {
     7     console.log("then方法的第二个参数")
     8 })
     9 .catch(() => {
    10     console.log("catch方法")
    11 })

    结果输出:  

      then方法的第二个参数
     
     
    then方法返回一个新的Promise实例(不是之前那个),故此可以写成链式调用,then方法之后再调用另一个then方法。这样的写法可以指定一组按照次序调用的回调函数,因为如果前面一个回调函数返回的依然是一个promise对象,那么下一个回调函数就会等待这个Promise的状态结果才调用。
     1 let p  = new Promise((resolve,reject) => {
     2     setTimeout(() => {
     3         console.log("Promise ----- p")
     4         resolve()
     5     },1000)
     6 })
     7 let p1 = new Promise((resolve,reeject) =>{
     8     console.log("Promise ----- p1")
     9     resolve(p)
    10 })
    11 p1.then(res => {
    12     console.log("then方法的第一个参数")
    13 })
    14 .catch(() => {
    15     console.log("catch方法")
    16 })

    返回结果的输出顺序:

      Promise ----- p1

      (两次输出之间间隔1秒)
      Promise ----- p
      then方法的第一个参数

     链式调用

     1 let p  = new Promise((resolve,reject) => {
     2     resolve()
     3 })
     4 p.then(() => {
     5     console.log("第一个then方法")
     6 })
     7 .then(() => {
     8     console.log("第二个then方法")
     9 })
    10 .then(() => {
    11     console.log("第三个then方法")
    12 })
    13 .then(() => {
    14     console.log("第四个then方法")
    15 })
    16 .then(() => {
    17     console.log("第五个then方法")
    18 })

    输出结果:

      第一个then方法
      第二个then方法
      第三个then方法
      第四个then方法
      第五个then方法
     

    catch方法

    发生错误时的回调函数。Promise对象的错误具有向后传递的性质,前面的错误(包括then方法中的错误或者前面一个catch中的错误)总是会被下一个catch捕获(捕获前面没有被捕获的错误,包括then的回调函数中抛出的错误)。

     
    1 let p  = new Promise((resolve,reject) => {
    2     reject()
    3 })
    4 p.then(() => {
    5     console.log("then方法的第一个参数")
    6 })
    7 .catch(() => {
    8     console.log("catch方法")
    9 })

    结果输出:

      catch方法

      

    catch捕捉then方法中的错误

     1 let p  = new Promise((resolve,reject) => {
     2     resolve()
     3 })
     4 p.then(() => {
     5     console.log("then方法的第一个参数")
     6     throw new Error("then 错误")
     7 })
     8 .catch(() => {
     9     console.log("catch方法")
    10 })

    输出结果: 

      then方法的第一个参数
      catch方法

    catch向后传递的特性

     1 let p  = new Promise((resolve,reject) => {
     2     reject()
     3 })
     4 p.then(() => {
     5     console.log("then方法的第一个参数")
     6 })
     7 .catch(() => {
     8     console.log("第一个catch方法")
     9     throw new Error("catch错误")
    10 })
    11 .then(() => {
    12     console.log("第二个then方法")
    13 })
    14 .catch(() => {
    15     console.log("第二个catch")
    16 })

    输出结果:

      第一个catch方法
      第二个catch

       

    finally方法

    不管Promise对象的状态是什么都会执行的操作。finally方法的回调函数不接受任何参数,则没有办法知道前端Promise的具体状态,换句话说finally不依赖于Promise的执行结果

     1 let p  = new Promise((resolve,reject) => {
     2     resolve()
     3 })
     4 p.then(() => {
     5     console.log("第一个then方法")
     6 })
     7 .catch(() => {
     8     console.log("第一个catch方法")
     9 })
    10 .finally(() => {
    11     console.log("finally")
    12 })

    输出结果:  

      第一个then方法

      finally

     1 let p  = new Promise((resolve,reject) => {
     2    reject()
     3 })
     4 p.then(() => {
     5     console.log("第一个then方法")
     6 })
     7 .catch(() => {
     8     console.log("第一个catch方法")
     9 })
    10 .finally(() => {
    11     console.log("finally")
    12 })

    输出结果:  

      第一个catch方法

      finally

    all方法

    all方法用于将多个Promise实例包装成一个新的Promise实例。新的Promise实例的状态由组成它的Promise实例的状态共同决定(个人感觉有点类似于&&运算符)。

    1> 多个Promise实例的状态都变成已完成(resolved)状态,新的Promise实例的状态才会变成已完成状态,并且将多个Promise实例的返回值组成一个数组传递给新的Promise的回调函数

    2> 多个Promise实例中,只要有一个实例的状态变成rejected,新的实例的状态就会变成rejecte,并且将第一个状态为rejected的实例的返回值传递给新的Promise实例的回调函数。

     1 let p1  = new Promise((resolve,reject) => { 3     resolve("p1")
     4 })
     5 let p2  = new Promise((resolve,reject) => { 7     resolve("p2")
     8 })
     9 let p3  = new Promise((resolve,reject) => {11     resolve("p3")
    12 })
    13 
    14 let p  = Promise.all([p1,p2,p3])
    15 p.then(res => {
    16     console.log('返回结果res -->',res)
    17 })
    18 .catch((error) => {
    19     console.log('返回错误error -->',error)
    20 })

    输出结果:

      返回结果res --> (3) ["p1", "p2", "p3"]

     1 let p1  = new Promise((resolve,reject) => { 3     resolve("p1")
     4 })
     5 let p2  = new Promise((resolve,reject) => { 7     reject("p2")
     8 })
     9 let p3  = new Promise((resolve,reject) => {11     resolve("p3")
    12 })
    13 
    14 let p  = Promise.all([p1,p2,p3])
    15 p.then(res => {
    16     console.log('返回结果res -->',res)
    17 })
    18 .catch((error) => {
    19     console.log('返回错误error -->',error)
    20 })

    输出结果:

      返回错误error --> p2

    race方法

    跟all方法相同,将多个Promise实例包装成一个新的Promise实例,只不过和all方法不同的是,race是哪个Promise先返回结果就取哪个Promise的结果,不会等待全部的Promise实例执行完。

    all方法返回的结果和参数中数组的有关系,但是race方法的返回结果和Promise实例的执行顺序有关。

     1 let p1  = new Promise((resolve,reject) => {
     2     resolve("p1")
     3 })
     4 let p2  = new Promise((resolve,reject) => {
     5     resolve("p2")
     6 })
     7 let p3  = new Promise((resolve,reject) => {
     8     resolve("p3")
     9 })
    10 
    11 let p  = Promise.race([p1,p2,p3])
    12 p.then(res => {
    13     console.log('返回结果res -->',res)
    14 })
    15 .catch((error) => {
    16     console.log('返回错误error -->',error)
    17 })

    输出结果:

      返回结果res --> p1

     1 let p1  = new Promise((resolve,reject) => {
     2     setTimeout(() => {
     3         resolve("p1")
     4     },1000)
     5 })
     6 let p2  = new Promise((resolve,reject) => {
     7     setTimeout(() => {
     8         resolve("p2")
     9     },1500)
    10 })
    11 let p3  = new Promise((resolve,reject) => {
    12     setTimeout(() => {
    13         reject("p3")
    14     },500)
    15 })
    16 
    17 let p  = Promise.race([p1,p2,p3])
    18 p.then(res => {
    19     console.log('返回结果res -->',res)
    20 })
    21 .catch((error) => {
    22     console.log('返回错误error -->',error)
    23 })

    输出结果:

      返回错误error --> p3

    小记:

    catch和then方法的第二个参数的区别:

    我们知道,then方法的是第二个参数和catch都是Promise状态变为rejected时执行的回调函数,但是我们一般不用then方法的第二个参数而总是使用catch方法,这是因为catch方法可以捕获到then方法中的错误,而then方法的第二个参数是捕捉不到的。

    ...

  • 相关阅读:
    SharePoint缓存配置
    修改默认的个人站点
    生成代码工具
    Ext 布局(layout)
    编程网站
    EXT 4.0 上传文件
    修改Ext grid 单元格
    Ext.tip.Tooltip 提示
    EXT iframe 应用
    EXT 4.0 TreeGrid 使用
  • 原文地址:https://www.cnblogs.com/wangrenmeng/p/10904855.html
Copyright © 2011-2022 走看看