侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

ES6基础之 Promise 对象用法实例详解

前端  /  管理员 发布于 5年前   344

本文实例讲述了ES6基础之 Promise 对象用法。分享给大家供大家参考,具体如下:

Promise 对象

1.Promise对象是ES6对异步编程的一种解决方案,它有以下两个特点:

  • Promise对象代表一个异步操作,它只有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败),并且该状态不会受外界的影响
  • Promise对象的状态改变,只有两种可能:从 Pending 变为 Resolved 或者从 Pending 变为 Rejected,并且一旦状态改变,就不会再变,任何时候都可以得到这个结果

2.Promise对象的一些缺点:

一旦新建了一个Promise对象,就会立即执行,并且无法中途取消

let promise = new Promise(function(resolve, reject) {console.log('Promise');resolve();});// Promise

如果不设置Promise对象的回调函数,Promise会在内部抛出错误,不会反应到外部,也就是在外部拿不到错误提示

如果Promise对象处于Pending状态时,是无法得知捕获进展到哪一个阶段的(刚刚开始还是即将完成)

3.Promise对象是一个构造函数,用来生成Promise实例,下面是创造了一个Promise实例的示例

let promise = new Promise(function(resolve, reject) { // ... to do if ( success ){  resolve(value);  //成功操作 } else {  reject(error);   //失败操作 }});

ps:Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject ,分别用来处理成功和失败的回调;

4.Promise实例生成以后,可以用 then 方法分别指定 Resolved 状态和 Reject 状态的回调函数;

promise.then(function(value) { // success}, function(error) { // failure});

ps:then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Rejected时调用,其中,第二个函数是可选的;

5.resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例,表示异步操作的结果有可能是一个值,也有可能是另一个异步操作;

let promise1 = new Promise(function (resolve, reject) { // ...});let promise2 = new Promise(function (resolve, reject) { // ... resolve(p1);})

上面代码表示一个异步操作的结果是返回另一个异步操作,promise1 的状态就会传递给 promise2 , 如果 promise1 的状态是Pending,那么 promise2 的回调函数就会等待promise1的状态改变;如果promise1的状态已经是Resolved或者Rejected,那么promise2的回调函数将会立刻执行;

6.Promise实例方法then返回的是一个新的Promise实例,因此可以采用链式写法,即then方法后面再调用另一个then方法

let promise = new Promise(function (resolve, reject) { // ...})promise.then(function(res) {  return res.post;}).then(function(post) {  // ...});

ps:上例中依次指定了两个回调函数,第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数,如果返回的是 Promise 对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用

let promise = new Promise(function (resolve, reject) { // ...})promise.then(function(res) {  return new Promise(/.../);}).then(function(res) {  // Resolved},function(error){  // Rejected});

7.Promise.prototype.catch 方法用于指定发生错误时的回调函数,不仅异步操作抛出错误(即状态就会变为Rejected),而且 then 方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获

let promise = new Promise(function(resolve, reject) {  throw new Error('test');}).catch(function(error) { console.log(error);});// Error: test

8.如果Promise状态已经变成Resolved,再抛出错误是无效的

let promise = new Promise(function(resolve, reject) { resolve('ok'); throw new Error('test');});promise .then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) }); //ok

ps: 出现上述结果是由于 之前提到的 Promise 的状态一旦改变,就永久保持该状态,不会再变了,因此在 resolve 语句后面,再抛出错误,是不会被捕获的

9.Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止,因此建议总是使用catch方法,而不使用then方法的第二个参数,因为使用catch方法可以捕获前面then方法执行中的错误

// badpromise .then(function(data) {  // success }, function(err) {  // error });// goodpromise .then(function(data) { //cb  // success }) .catch(function(err) {  // error });

10.Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,该方法接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法。

var p1 = new Promise(function (resolve) {  setTimeout(function () {    resolve("Hello");  }, 3000);});var p2 = new Promise(function (resolve) {  setTimeout(function () {    resolve("World");  }, 1000);});Promise.all([p1, p2]).then(function (result) {  console.log(result);  // ["Hello", "World"]});

上面的例子模拟了传输两个数据需要不同的时长,虽然 p2 的速度比 p1 要快,但是 Promise.all 方法会按照数组里面的顺序将结果返回,但 promise 本身并不是一个个的顺序执行的,而是同时开始、并行执行的,可以利用这个特点处理需要多个回调返回后才能进行的操作

11.Promise.race方法和Promise.all方法类似,也接收一个promise对象数组为参数,不同的是只要该数组中的 Promise 对象的状态发生变化(无论是 resolve 还是 reject)该方法都会返回。

var p1 = new Promise(function (resolve) {setTimeout(function () {resolve("Hello");}, 3000);});var p2 = new Promise(function (resolve) {setTimeout(function () {resolve("World");}, 1000);});Promise.race([p1, p2]).then(function (result) {console.log(result);  // Wrold});

12.一般情况下我们都会使用 new Promise() 来创建promise对象,除此之外,可以使用 Promise.resolve 和 Promise.reject这两个方法;

静态方法Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式

let promise = Promise.resolve('resolved');//等价于let promise = new Promise(function(resolve){resolve('resolved');});

上述的promise对象立即进入确定(即resolved)状态,并将 'resolved' 传递给后面then里所指定的 onFulfilled 函数。

Promise.resolve('resolved').then(function(value){console.log(value);});// resolved

Promise.reject(error)是和 Promise.resolve(value) 类似的静态方法,是 new Promise() 方法的快捷方式。

let promise = Promise.reject(new Error("出错了"));//等价于let promise = new Promise(function(resolve,reject){reject(new Error("出错了"));});

上述 promise 对象通过then指定的 onRejected 函数,并将错误(Error)对象传递给这个 onRejected 函数

Promise.reject(new Error("fail!")).catch(function(error){console.error(error);});// Error : fail!

13.我们可以利用 Promise 应用到我们实际开发中,下面举几个栗子

//图片加载const preloadImage = function (path) { return new Promise(function (resolve, reject) {  var image = new Image();  image.onload = resolve(image);  image.onerror = function() {    reject(new Error('Could not load image at ' + path));  };  image.src = path; });}//文件读取function reader (file) { return new Promise(function (resolve, reject) {  let reader = new FileReader();  reader.onload = function () {   resolve(reader);  };  reader.onerror = function() {    reject(new Error('Could not open the file ' + file));  };  if (!file.type || /^text\//i.test(file.type)) {   reader.readAsText(file);  } else {   reader.readAsDataURL(file);  } })}

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools..net.cn/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

您可能感兴趣的文章:

  • ES6 Promise对象的应用实例分析
  • ES6 Promise对象的含义和基本用法分析
  • 详解ES6 Promise对象then方法链式调用
  • ES6新特性六:promise对象实例详解
  • ES6 Promise对象概念与用法分析
  • ES6中异步对象Promise用法详解
  • 让你彻底掌握es6 Promise的八段代码
  • 浅析Javascript ES6中的原生Promise
  • ES6关于Promise的用法详解
  • 如何利用ES6进行Promise封装总结
  • ES6 Promise对象概念及用法实例详解


  • 上一条:
    ES6基础之数组和对象的拓展实例详解
    下一条:
    简述ES6新增关键字let与var的区别
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客