javaScript中Promise深度理解

半人马酋长
• 阅读 2854

用途

用于处理异步操作,避免地狱式回调,比如ajax请求,处理起来更加简单方便,代码看起来也更容易理解,便于维护。

概念

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。 Promise共有三种状态,相应状态会触发相应的回调函数。

  • pending: 初始状态。什么回调函数也不触发。

    • 调用构造函数如new Promise((resolve, reject) => {}),在这个exextutor函数中要么调用resolve是状态改为完成,要么调用reject使状态改为失败,要么就什么都不调用,这个时候就是pending状态,此时[[PromiseValue]]undefined

          var result = new Promise((resolve, reject) => {
          
          })
    • .then.catch中返回值为上面直接使用构造函数的情况,并且在其内部也什么都不返回,那么这个时候也是pending

          var result = new Promise((resolve, reject) => {
              resolve('xxx')
          }).then((res) => {
              return new Promise((resolve, reject) => {
          
              })
          })
    • .then.catch中无返回值的时候,这个时候返回的状态为前面的Promise的状态,如果前面的状态为pending,那么这里返回的也是pending,只不过没有返回值,返回的Promise[[PromiseValue]]undefined

          var result = new Promise((resolve, reject) => {
              
          }).then((res) => {
      
          })
  • fulfilled: 成功状态。触发绑定的‘onfulfilled’方法。

    • executor函数中调用resolve

        var result = new Promise((resolve, reject) => {
            resolve('xxx')
        })
    • .then .catch中调用Promsie.resolve

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           return Promise.resolve('bbbb')
       })
    • .then .catch中的返回值为一个普通值,值作为[[PromiseValue]]`的值。

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           return 'xxxx'
       })
    • .then.catch中无返回值的时候,这个时候返回的状态为前面的Promise的状态,如果前面的状态为resolved,那么这里返回的也是resolved,只不过没有返回值,返回的Promise[[PromiseValue]]undefined

          var result = new Promise((resolve, reject) => {
              resolve('xxx')
          }).then((res) => {
              
          })
  • rejected: 失败状态。触发绑定的‘onrejected’方法。

    • executor函数中调用rejecte

        var result = new Promise((resolve, reject) => {
            reject('xxx')
        })
    • .then .catch中调用Promsie.reject

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           return Promise.reject('bbbb')
       })
    • .then .catch中抛出一个错误时,状态改为rejected,并且触发onrejected函数,错误信息将作为作为拒绝状态的回调函数的参数值和拒绝状态的Promise[[PromiseValue]]的值。

       var result = new Promise((resolve, reject) => {
             resolve('xxx')
       }).then((res) => {
           throw 'xxxx'
       }).catch((err) => {
            console.log(err) // xxxx
       })
       console.log(result) // {[[PromiseStatus]]: "rejected",  [[PromiseValue]]: "xxxx"}

.then

p.then(onFulfilled, onRejected);

当状态变成成功状态的时候调用onFulfilled, 当状态变成失败的时候,调用onRejected。它返回一个Promise,而它的行为与then中的回调函数的返回值有关:

  • 如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
  • 如果then中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
  • 如果then中的回调函数返回一个已经是接受状态的Promise,那么then返回的Promise也会成为接受状态,并且将那个Promise的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
  • 如果then中的回调函数返回一个已经是拒绝状态的Promise,那么then返回的Promise也会成为拒绝状态,并且将那个Promise的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
  • 如果then中的回调函数返回一个未定状态(pending)的Promise,那么then返回Promise的状态也是未定的,并且它的终态与那个Promise的终态相同;同时,它变为终态时调用的回调函数参数与那个Promise变为终态时的回调函数的参数是相同的。

Promise.resolve

参数可以是三种参数类型

  • Promise.resolve(value);
  • Promise.resolve(promise);
  • Promise.resolve(thenable);

如果参数类型是普通的值那么返回的Promise状态仍然是resolve,值为返回的值,如果返回值是另外两种情况,那么返回的Promise的状态由返回值来决定。例如下面的例子返回的是reject,值为xxxx

        var result = Promise.resolve(new Promise((resolve, reject) => {
                reject('xxxx')
        }))

Promise.reject

接收一个参数,但是参数不会影响返回的Promise结果,通过Promise.reject返回的状态始终都是reject

Promise.all

当我们需要并行执行多个异步的时候,就可以使用这个方法,该方法接收一个可以迭代的对象,例如数组,数组中一般都是我们需要并行运行的Promise对象,如果是普通值那么也会直接返回。只有每一项都为resolve时,才会调用.then中的成功方法,并且回调参数值一个包含前面所有结果的数组,并且顺序也和前面一样,否则调用失败的回调。看个例子

var a = 1
var b = new Promise((resolve, reject) => {
    setTimeout(function(){
        resolve('xxxx')
    }, 1000)
})
var c = Promise.resolve('aaa')
var result = Promise.all([a, b, c]).then((values) => {
    console.log(values) // 1, xxx, aaa
}).catch((err) => {
    console.log(err)
})

对于Promise.all的同步或者异步,如果值是空的可迭代对象,那么将是同步的,其他情况均为异步。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Chase620 Chase620
4年前
Promise从入门到拿Offer之手写Promise
1、Promise构造函数的实现Promise构造函数用来声明示例对象,需要传入一个执行器函数。其中包括resolve函数和reject函数,以及几个重要的属性:状态属性、结果属性和回调函数队列。构造函数的基本框架resolve函数用于异步处理成功后调用的函数。其中包括验证对象状态修改次数,修改promise实例对象状态,异步调用成功的回调函数
Wesley13 Wesley13
3年前
JavaWeb 之 JSON
一、概述  1、概念JSON:JavaScriptObjectNotation JavaScript对象表示法  2、基本格式varp{"name":"张三","age":23,"sex":"男"};  3、用途和优点(1)json现在多用于存储
Stella981 Stella981
3年前
JavaScript的 基本数据类型
第一:Javascript对象是第二:Javascript中第三:Javascript的对象是数据;第四:JavaScript中的对象可以简单理解成"名称:值"对(name:value)。名称(name):"名称"部分是一个JavaScript字符串参考https://www
Stella981 Stella981
3年前
JavaScript回调函数的高手指南
摘要:本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步。回调函数是每个前端程序员都应该知道的概念之一。回调可用于数组、计时器函数、promise、事件处理中。本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步。1.回调函数首先写一个向人打招呼的函数。只需要创建一个接受name参数的函数gree
Stella981 Stella981
3年前
ES6 Promise 对象扯谈
newPromise(/executor/function(resolve,reject){...});Promise的构造函数接收一个函数作为参数,函数里面传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用“成功”和“失败”来描述并不准确,按照标准来
Stella981 Stella981
3年前
Promise 多重链式调用
Promise对象是用于异步操作的。Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。如果我们在第一次ajax请求后,还要用它返回的结果再次请求呢?使用Promise,我们就可以利用then进行「链式回调」,将异步操作以同步操作的流程表示出来。以下是个小Demo:/e.g/sen
Wesley13 Wesley13
3年前
Oracle一张表中实现对一个字段不同值和总值的统计(多个count)
需求:统计WAIT\_ORDER表中的工单总数、未处理工单总数、已完成工单总数、未完成工单总数。表结构:为了举例子方便,WAIT\_ORDER表只有两个字段,分别是ID、STATUS,其中STATUS为工单的状态。1表示未处理,2表示已完成,3表示未完成总数。 SQL:  1.SELECT   2
Promise规范与原理解析 | 京东物流技术团队
Promise对象用于清晰的处理异步任务的完成,返回最终的结果值,本次分享主要介绍Promise的基本属性以及Promise内部的基础实现,能够帮我们更明确使用场景、更快速定位问题。
京东云开发者 京东云开发者
5个月前
Promise规范与原理解析
作者:京东物流孙琦摘要Promise对象用于清晰的处理异步任务的完成,返回最终的结果值,本次分享主要介绍Promise的基本属性以及Promise内部的基础实现,能够帮我们更明确使用场景、更快速定位问题。Promise出现的原因首先我们先来看一段代码:异步
美凌格栋栋酱 美凌格栋栋酱
4个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(