Promise异步编程

2023-05-16

目录

一、Promise的含义

二、基本用法

三、reject的用法

四、执行顺序

五、  项目中使用promise获取后端数据

六、catch的用法

七、finally的用法

八、Promise.all()

九、Promise.all()有一个是失败

十、Promise.race()全部是成功

十一、Promise.race()有一个是失败

十二、Promise.resolve()

十三、Promise.reject()

十四、promise.try()

十五、Promise 封装ajax


一、Promise的含义

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

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

promise翻译: 许诺;承诺;答应;保证;使很可能;预示

二、基本用法

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

  const baseFun = () => {
    console.log(1)
    const promise = new Promise(function (resolve, reject) {
      setTimeout(() => {
        resolve({
          code: 200,
          data: {
            title: '通过resolve返回的数据',
          },
          msg: '成功',
        })
      }, 1000)
    })
    promise.then((res) => {
      if (res.code === 200) {
        setTitle(res.data.title)
      }
    })
  }

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

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

三、reject的用法

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数。

  //reject的用法
  const baseRejectFun = () => {
    const promise = new Promise(function (resolve, reject) {
      setTimeout(() => {
        reject({
          code: 400,
          data: {
            title: '通过reject返回的数据',
          },
          msg: '失败',
        })
      }, 1000)
    })
    promise.then(
      (res) => {
        if (res.code === 200) {
          setTitle(res.data.title)
        }
      },
      (res) => {
        if (res.code === 400) {
          setTitle(res.data.title)
        }
      }
    )
  }

四、执行顺序

Promise 新建后就会立即执行。

  //执行顺序
  const baseOrderFun = () => {
    const promise = new Promise(function (resolve, reject) {
      console.log('promise')
      resolve()
      console.log('promise2')

    })
    promise.then((res) => {
      console.log('resolved')
    })
    console.log('other')
  }

Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。

五、项目中使用promise获取后端数据

  //项目中使用promise获取后端数据
  const baseApiFun = () => {
    Api.h5.userGetInfo({}).then((res) => {
      if (res.code === 200) {
        setTitle(res.data.nickname)
      }
  })

六、catch的用法

Promise.prototype.catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

  //catch的用法
  const baseCatchFun = () => {
    const promise = new Promise(function (resolve, reject) {
      setTimeout(() => {
        reject({
          code: 400,
          data: {
            title: '通过reject返回的数据',
          },
          msg: '失败',
        })
      }, 1000)
    })
    promise
      .then((res) => {
        if (res.code === 200) {
          setTitle(res.data.title)
        }
      })
      .catch((res) => {
        if (res.code === 400) {
          setTitle(res.data.title)
        }
      })
  }

一般来说,不要在then()方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

七、finally的用法

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

  //finally的用法
  const baseFinallyFun = () => {
    const promise = new Promise(function (resolve, reject) {
      setTimeout(() => {
        reject({
          code: 400,
          data: {
            title: '通过reject返回的数据',
          },
          msg: '失败',
        })
      }, 1000)
    })
    promise
      .then((res) => {
        if (res.code === 200) {
          setTitle(res.data.title)
        }
      })
      .catch((res) => {
        if (res.code === 400) {
          setTitle(res.data.title)
        }
      }).finally(() => {
        console.log('finally')
      })
  }

八、Promise.all()

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

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

上面代码中,Promise.all()方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

p的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

  //Promise.all()
  const baseAllFun = () => {
    const promise1 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        resolve({
          code: 200,
          data: {
            title: '通过resolve返回的数据',
          },
          msg: '成功',
        })
      }, 1000)
    })
    const promise2 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        resolve({
          code: 200,
          data: {
            title: '通过resolve返回的数据2',
          },
          msg: '成功2',
        })
      }, 1000)
    })
    const promiseAll = Promise.all([promise1, promise2])
    promiseAll
      .then((res) => {
        console.log(res)
      })
      .catch((res) => {
        if (res.code === 400) {
          setTitle(res.data.title)
        }
      })
  }

九、Promise.all()有一个是失败

  //Promise.all()有一个是失败
  const baseAllWithRejectFun = () => {
    const promise1 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        reject({
          code: 400,
          data: {
            title: '通过reject返回的数据',
          },
          msg: '失败',
        })
      }, 1000)
    })
    const promise2 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        reject({
          code: 400,
          data: {
            title: '通过reject返回的数据2',
          },
          msg: '失败2',
        })
      }, 1000)
    })
    const promiseAll = Promise.all([promise1, promise2])
    promiseAll
      .then((res) => {
        console.log(res)
      })
      .catch((res) => {
        console.log('catch', res)
      })
  }

十、Promise.race()全部是成功

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

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

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

  const baseRaceFun = () => {
    const promise1 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        resolve({
          code: 200,
          data: {
            title: '通过resolve返回的数据',
          },
          msg: '成功',
        })
      }, 5000)
    })
    const promise2 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        resolve({
          code: 200,
          data: {
            title: '通过resolve返回的数据2',
          },
          msg: '成功2',
        })
      }, 1000)
    })
    const promiseRace = Promise.race([promise1, promise2])
    promiseRace
      .then((res) => {
        console.log(res)
      })
      .catch((res) => {
        console.log(res)
      })
  }

十一、Promise.race()有一个是失败

  //Promise.race()有一个是失败
  const baseRaceWithRejectFun = () => {
    const promise1 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        resolve({
          code: 200,
          data: {
            title: '通过resolve返回的数据',
          },
          msg: '成功',
        })
      }, 5000)
    })
    const promise2 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        reject({
          code: 400,
          data: {
            title: '通过reject返回的数据2',
          },
          msg: '失败2',
        })
      }, 1000)
    })
    const promiseRace = Promise.race([promise1, promise2])
    promiseRace
      .then((res) => {
        console.log(res)
      })
      .catch((res) => {
        console.log('catch', res)
      })
  }

十二、Promise.resolve()

      //将现有对象转为 Promise 对象
      let promise = Promise.resolve(1)
      promise.then((res) => {
        console.log(res) //1
      })

十三、Promise.reject()

      //将现有对象转为 Promise 对象
      let promise = Promise.reject(1)
      promise
        .then((res) => {})
        .catch((res) => {
          console.log('catch', res) //catch 1
        })

十四、promise.try()

处于提案阶段,还没有实现

javascript - Promise.try is not a function - SegmentFault 思否

 

十五、Promise 封装ajax

XMLHttpRequest(XHR)对象用于与服务器交互

XMLHttpRequest.open() 方法初始化一个新创建的请求

XMLHttpRequest.send() 方法用于发送 HTTP 请求

当一个XMLHttpRequest请求完成的时候会触发load 事件

XMLHttpRequest - Web API 接口参考 | MDN

      const xhr = new XMLHttpRequest()
      xhr.open('post', 'http://yuying-api.xutongbao.top/api/light/user/captcha')
      xhr.send()
      xhr.addEventListener('load', (e) => {
        let res = JSON.parse(e.target.response)
        console.log(res)
        if (res.code === 200) {
          document.getElementById('img').innerHTML = res.data.captcha
        }
      })

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="img"></div>
    <script>
      const ajax = ({ method = 'get', url }) => {
        return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest()
          xhr.open(method, url)
          xhr.send()
          xhr.addEventListener('load', (e) => {
            let res = JSON.parse(e.target.response)
            resolve(res)
          })
        })
      }
      ajax({
        method: 'post',
        url: 'http://yuying-api.xutongbao.top/api/light/user/captcha',
      }).then((res) => {
        console.log(res)
        if (res.code === 200) {
          document.getElementById('img').innerHTML = res.data.captcha
        }
      })
    </script>
  </body>
</html>

开源项目地址:

https://github.com/xutongbao/learn-chatgpt

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Promise异步编程 的相关文章

  • Jpa 插入更新如何过滤null值

    使用Jpa时 xff0c 默认的save方法会将entity中null的值也更新到数据库 xff0c 这对与存在默认值或者更新接口将直接导致错误的记录产生 xff0c 那么如何解决这个问题 xff1f Hibernate提供了两个注解 64
  • 一个奇怪的java.lang.IncompatibleClassChangeError异常

    解决方法就是替换jdk版本 xff0c 下面都是废话 最近项目进行了一次小更新 xff0c 添加了一个很小很小的功能 xff0c 结果运行一段时间后莫名出现java lang IncompatibleClassChangeError xff
  • nginx的proxy_pass最后反斜杠/的问题

    如果只是host xff0c 如http host 带 xff1a 用代理的内容替换掉匹配的路径 不带 xff1a 拼接上匹配的路径 2 xff1a 如果是子路径 xff0c 如http host func 带和不带 xff1a 用代理的内
  • gitlab修改克隆地址

    1 修改gitlab yml文件 xff0c 修改gitlab下的host和port vi opt gitlab embedded service gitlab rails config gitlab yml 修改完成后执行gitlab c
  • 结构体成员——数组或指针

    结构体成员是C类型的字符数组 表示字符串时 c语言中没有字符串类型 xff0c 只能使用字符数组表示字符串 当定义结构体时 xff0c 成员是字符数组时 xff0c 在外部给该成员赋值 xff0c 不能使用 结构体把变量名 成员名 61 3
  • C++遍历输出enum枚举类型

    enum DAY MON TUE WED THU FRI SAT SUN 问题 如果使用如下方式来遍历 xff0c 则编译器会报类型转换失败错误 xff0c 因为enum类型没有 43 43 运算符 xff0c 也不支持 43 运算 for
  • Kali Linux

    为什么我输入git clone 43 网址显示无法访问啊
  • Android自定义标题栏异常You cannot combine custom titles with other title features

    我们在使用自定义标题栏时 xff0c 一般的写法基本上是下面几步 requestWindowFeature Window FEATURE CUSTOM TITLE setContentView R layout activity test
  • Kotlin中使用Dagger2 可能导致错误"Dagger does not support injection into private fields"

    Kotlin 生成 java文件时属性默认为 private xff0c 给属性添加 64 JvmField 声明可以转成 public class User var name String 61 null val age Int 61 2
  • [linux]ubuntu22安装mysql5.7.40

    导语 xff1a ubuntu22 04 强制安装mysql5 7 40 安装完安装其他apt依赖的时候 可能会造成mysql出问题 最好还是离线环境用 apt update apt get install zip y cd var rm
  • winxp 远程rdp 连接 Ubuntu10.10-再次远程登陆失败 (二)

    在文章winxp 远程rdp 连接 Ubuntu10 10 一 操作完成 xff0c 并且进行第一成功登陆之后 xff0c 退出 xff08 注销 直接关闭mstsc退出按钮 xff09 远程连接之后 xff0c 重新登录出现 xff0c
  • PostGIS教程七:几何图形(Geometry)

    目录 一 介绍 二 元数据表 三 表示真实世界的对象 3 1 点 xff08 Points xff09 3 2 线串 xff08 Linestring xff09 3 3 多边形 xff08 Polygon xff09 3 4 集合 xff
  • FreeBSD下修改安装源的方法

    FreeBSD默认是从官方的源下载软件包的 xff0c 速度比较慢 xff0c 可以修改配置文件指定国内的镜像源来快速安装软件 说明 xff1a FreeBSD中安装软件一般有两种方式 xff1a xff08 一 xff09 使用pk ad
  • sqlite3_bind

    sqlite3 bind text 中绑定的指针 xff0c 在sqlite3 step 时必须存在 xff0c 不能释放 xff0c 否则会是乱码 sqlite3 bind blob中绑定的指针 xff0c 在sqlite3 step 时
  • Windows10 Clion 无法打开文件cudart.lib

    真是巨坑 xff0c 遇到这个问题 xff0c 且耗费两个小时百度 google xff0c 差点放弃换用Visual Studio xff0c 但真实原因竟然这么简单 在你的CmakeList txt中 xff0c 是不是这样添加cuda
  • cf规则介绍

    codeforces的正确打开方式 1 背景 可能很多人都久闻codeforces网站的大名 xff0c 却苦于各种各样的区域性问题或玄学问题 xff0c 没能真正地体验到cf所带来的极致魅力 而网络上关于这方面的博文太少了 xff08 至
  • 使用Buildroot + QEMU构建和运行Linux

    使用Buildroot 43 QEMU构建和运行Linux xunknown 64 2022 04 06 概述 Buildroot是一个用于为嵌入式系统构建完整的Linux系统 xff08 包括Bootloader xff0c Linux
  • openwrt 无线中继设置–固定IP+打印服务器和文件共享

    openwrt 无线中继设置 固定IP 43 打印服务器和文件共享 因为给TPLINK703N xff0c 编译16MROM成功 xff0c 固件里加入了打印服务器和SAMBA VSFTPD USB挂载等功能 xff0c 可使用有线连接上级
  • Linux 终端(TTY)

    原文 xff1a Linux 终端 TTY sparkdev 博客园 Linux 终端 TTY TTY 是 Teletype 或 Teletypewriter 的缩写 xff0c 原来是指电传打字机 xff0c 后来这种设备逐渐键盘和显示器
  • shell命令和变量//区分变量未定义和变量已定义但值为空

    转载 xff1a Shell Command Language 参考 xff1a shell How to check if a variable is set in Bash Stack Overflow 关键 xff1a 形如 para

随机推荐

  • 区分本地终端和ssh远程终端

    如果本地和远端服务器用户名和主机名 xff0c 终端颜色配置都一致 xff0c 通过ssh登陆服务器的时候 xff0c 在本地终端和ssh终端来回切换时 xff0c 傻傻分不清当前终端是本地终端还是ssh远程服务器 下面这个连接介绍了一种方
  • 电路仿真软件Circuit JS1修改菜单字体大小

    在线演示 xff1a https www falstad com circuit circuitjs html 下载地址 xff1a https www falstad com circuit offline circuitjs1 linu
  • Ubuntu 22.04配置samba服务器

    安装samba sudo apt install samba 可以验证一下安装结果 xff1a smbd version 创建samba用户密码 创建samba用户 xff08 可选 xff09 xff1a sudo adduser sys
  • 一个查找文件的类:它的长处在于能够搜索子目录并且是可控制的

    find file cpp Defines the entry point for the console application include 34 stdafx h 34 测试需要的头文件 include lt conio h gt
  • Clearwater IMS All-in-one环境搭建指导书

    xunknown 64 163 com 2015 01 13 一 前言 Clearwater IMS 是一个开源的 IMS 项目 提供 VoIP SIP 电话等功能 Clearwater IMS 主页 http www projectcle
  • Clearwater IMS All-in-one环境搭建指导书

    xunknown 64 163 com 2015 01 13 一 前言 Clearwater IMS 是一个开源的 IMS 项目 提供 VoIP SIP 电话等功能 Clearwater IMS 主页 http www projectcle
  • Sublime Text3注册码(亲测可用 2019-11-19)

    转自博客中的朋友的 xff0c 用于保存 适用于Sublime Text2同时也适用于Sublime Text3 1 打开本地hosts文件 Windows路径是C Windows System32 drivers etc MacOS路径是
  • H3C配置多区域OSPF实验

    一 先上拓扑 xff1a 二 实验环境 xff1a Windows 10 xff08 21H1 xff09 xff0c HCL版本 xff1a V3 0 1 xff08 华三模拟器 xff09 三 实验需求 xff1a SWA SWB SW
  • 配置mysql使用ssl连接,配置java连接mysql使用ssl

    查看mysql是否支持ssl连接 show variables like 39 ssl 39 生成服务器端 openssl genrsa 2048 gt ca key pem openssl req sha1 new x509 nodes
  • Python中的命名规范

    变量命名准则 您应当尽量使自己的变量命名含义清晰 xff0c 不要使用混乱的字母 数字 表情等意义不明的字符来命名变量一般来说 xff0c 您不应当使自己的风格频发变换 如果可能 xff0c 请将整个项目保持统一风格此文章根据本人习惯与编码
  • Linux下达梦数据库的安装与卸载

    文章目录 Linux下达梦数据库的安装与卸载1 安装前准备工作1 1 下载安装包1 2 检查Linux Unix 系统信息1 3 创建安装用户1 4 Linux Unix 下检查操作系统限制1 5 设置JAVA环境 2 安装DM2 1 解压
  • 递归算法实现角谷定理

    问题重述 xff1a 角谷定理 输入一个自然数 xff0c 若为偶数 xff0c 则把它除以 2 xff0c 若为奇数 xff0c 则把它乘以 3 加 1 经过如此有限次运算后 xff0c 总可以得到自然数值 1 求经过多少次可得到自然数
  • windows系统关闭node进程

    taskkill f t im node exe Node js是一个开源的 跨平台的JavaScript运行时环境 xff0c 它允许开发者在服务器端使用JavaScript进行编程 Node js的诞生极大地扩展了JavaScript的
  • 我的GPT-4 API 接入之旅

    3月15日open ai推出GPT 4 https platform openai com docs models gpt 4 chatgpt免费体验入口 xff1a http chat xutongbao top 需要排队 28号加入等候
  • IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

    git exe pull progress v no rebase 34 origin 34 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 6
  • 制作高清chatgpt logo

    lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt meta http equiv 61 34 X U
  • react开发前端登录、注册、找回密码页面的详细教程

    登录 注册 找回密码是前端项目经常遇到的需求 光标自动定位到输入框 回车登录 图形验证码 邮箱验证码 60秒倒计时 字段校验 字段提示语 上传头像 密码显示隐藏这些功能都会在本文中详细介绍 xff0c 注意 使用的ui库是antd 目录 光
  • azure windows服务器,远程桌面链接,ftp文件上传下载

    解决方案 xff1a FTP 安装filezilla 打开21端口 参考链接 xff1a Windows11 10 使用RDP远程桌面时提示 您的凭据不工作 登录没有成功可能的一种原因 CSDN博客 使用 SSH 连接到运行 Windows
  • LED的使用纯汇编和C语言的点亮

    概述 我们通过观察原理图可以发现LED灯有四个分别连接在GPM4 1 GPM4 2 GPM4 3 GPM4 4上面 xff0c 这时候我们去查询我们板子4412的说明书 xff0c 去寻址寄存器的配置 初始化的时候我们需要将他配置为输出模式
  • Promise异步编程

    目录 一 Promise的含义 二 基本用法 三 reject的用法 四 执行顺序 五 项目中使用promise获取后端数据 六 catch的用法 七 finally的用法 八 Promise all 九 Promise all 有一个是失