ES6学习笔记(三)——Promise对象

JavaScript -- ES6的Promise 本文系统讲解了Promise在前端异步编程中的应用。首先分析回调函数的缺点(嵌套地狱),重点介绍Promise的实现原理:通过返回Promise对象和.then()链式调用实现异步顺序执行,并说明传参和错误处理机制。同时介绍了ES7的async/await语法糖,可消除.then()嵌套。还详细解析了Promise.all()和Promise.any()等原型方法的使用场景,通过商品查询案例演示其实际应用。最后预告将分享手写Promise的实现过程,帮助开发者深入理解异步编程原理。 阅读详情

Promise的含义

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

注意,为了行文方便,本章后面的resolved统一只指fulfilled状态,不包含rejected状态。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)


基本用法

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

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,这两个是函数,由js引擎提供,不用自己部署。
resolve(reject):将Promise对象的状态从pending变为resolved(rejected),在异步操作成功(失败)时调用,并将异步操作的结果(异步操作报出的错误),作为参数,即上面的value,传递出去。
Promise实例生成后,可以用then 方法分别指定resolved状态和rejected状态的回调函数。

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

then方法接受两个回调函数,第一个函数是Promise对象的状态变为resolved时调用,第二个回调函数(optional)是Promise对象的状态变为rejected时调用。这两个函数都接受Promise对象传出的值(上面的value)作为参数。
Promise的异步回调例子:

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

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

Promise新建后立即执行,所以先输出Promisethen方法指定的回调函数,在当前脚本所有同步任务执行完之后才会执行,所以先下一步输出Hi! ,最后才是resolved 。
Promise对象实现Ajax操作例子:

const getJSON = function(url) {
  const promise = new Promise(function(resolve, reject){
    const handler = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

上面例子中,getJSON 返回一个promise对象实例。执行getJSON("/post.json") 时,发生了这些事情:

  1. 新建Promise对象,promise,传入参数function(resolve, reject){...}
  2. 在传入的function中,使用函数表达式声明handler函数,作为响应操作。
  3. 新建XMLHttpRequest 对象,发起请求…
  4. 当请求成功时,执行handler 中的操作 ,如果 promise 的状态变为resolved,触发then方法绑定的回调函数function(json){...} 并把 this.response 传入参数json 。

Promise.prototype.then()

syntax: ...then.(resolve, reject(optional))
then方法返回的是一个新的Promise实例,所以then后面可以再调用一个then。
这里写图片描述
采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function funcA(comments) {
  console.log("resolved: ", comments);
}, function funcB(err){
  console.log("rejected: ", err);
});

第一个then方法指定的回调函数function(post){...} ,返回另一个Promise对象。第二个then指定的回调函数,等待这个新的Promise对象状态发生变化。如果变为resolved,调用funA ,如果变为rejected,调用funB 。
采用箭头函数写法可以让上面的代码更简洁:

getJSON("/post/1.json").then(
  post => getJSON(post.commentURL)
).then(
  comments => console.log("resolved: ", comments),
  err => console.log("rejected: ", err)
);

Promise.prototype.catch()

Promise.prototype.catch 是.then(null, rejection) 的别名,用于指定发生错误时的回调函数。
如果Promise在resolve 函数执行后抛出错误,该错误不会被捕获,因为Promise的状态已经变成resolved了,一旦改变状态,就定态了。
Promise对象的错误有“冒泡”的性质,会一直向后传递,直到被捕获,也就是遇到下一个catch语句。

getJSON('/post/1.json').then(function(post) {
  return getJSON(post.commentURL);
}).then(function(comments) {
  // some code
}).catch(function(error) {
  // 处理前面三个Promise产生的错误
});

一般建议,不要使用then函数的第二个参数(Promise变为rejected状态的回调函数),而用catch方法,这样总能捕获前面then执行中的错误。
如果没有catch错误,Promise对象抛出的错误不会传递到外层代码,通俗讲,“Promise会吃掉错误”。


Promise.all()

将多个Promise实例,包装成一个新的Promise实例。

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

如果p1,p2,p3不是Promise的实例,会调用Promise.resolve 方法,将参数转为Promise实例。
只有p1,p2,p3的状态都为resolved,p的状态才会变为resolved;p1,p2,p3中任意一个状态变为rejected,p的状态就变为rejected,此时第一个被reject的实例的返回值,传递给p的回调函数。
[Note]
如果作为参数的Promise实例,有自己的catch方法,那么它被rejected之后,通过catch方法返回一个新的resolved的Promise实例,所谓“知错能改”,不会触发Promise.all的catch方法。

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

这里写图片描述

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// Error: 报错了

这里写图片描述


Promise.race()

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

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。


Promise.resolve()

将现有对象转化为Promise对象。
Promise.resolve(para)

  • 参数是一个Promise实例,则原封不动返回这个实例。
  • 参数是一个thenable对象,thenable对象是指具有then方法的对象,如下例子,Promise.resolve方法会将这个对象转为Promise对象,然后立刻执行他的then方法。
let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

let p1 = Promise.resolve(thenable);
p1.then(function(value) {
  console.log(value);  // 42
});
  • 参数不是具有then方法的对象,或者根本不是对象。
    Promise.resolve方法返回一个新的Promise对象,状态为resolved。
const p = Promise.resolve('Hello');

p.then(function (s){
  console.log(s)
});
// Hello

例子中,回调函数立刻执行。

  • 不带任何参数
    直接返回一个resolved状态的Promise对象。
setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log(‘one’)则是立即执行,因此最先输出。


Promise.reject()

Promise.reject(reason) 返回一个状态为rejected的新的Promise实例。参数reason会原封不动地作为reject的理由,变成后续方法的参数。

const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
// true

上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。


附加方法done()、finally()

超详细的ES6学习笔记 ES6笔记 1.let和const关键字 2.解构赋值 ​3.函数 4.数组 5.字符串 6. 对象 7. Promise 对象 阅读详情

相关推荐

OpenClaw 核心命令深度解析:/think high、/reasoning on、/verbose on 功能与实战指南

本文深入解析OpenClaw框架的三大核心命令:/think high实现极限深度推理,突破常规思考瓶颈;/reasoning on提供透明化推理过程,增强决策可信度;/verbose on控制详细输出级别。文章从技术架构、实现原理、配置方法和典型场景四个维度,详细阐述了各命令的功能特性与实战应用,包括法律分析、代码调试和商业决策等复杂场景的最佳实践。同时提供了多级配置方案和资源消耗参考,帮助用户根据任务复杂度灵活调配AI资源,实现效率与深度的最优平衡。

qq_43344878的博客 943

ES6的Promise详解

本篇文章主要介绍了ES6语法中的Promise对象的使用详解,promise对象是JS进阶学习中的重要知识点,如果本文对你有所帮助请三连支持博主,你的支持是我更新的动力,先赞后看养成习惯。以下是本篇文章正文内容。

程序员柒的博客 6084

基于STM32的多参数水质检测仪系统 | 保姆式教程 开源可复刻

本项目基于STM32F103C8T6主控,搭配pH、TDS、浊度、水温四大核心水质检测模块,完整实现了多参数水质检测仪的全流程开发,从多通道ADC采集、数字滤波、温度补偿、专业校准、阈值报警到人机交互,全流程无跳步保姆式拆解,配套逐行注释可直接编译的开源代码,新手跟着步骤一步步操作,就能顺利完成项目复刻

ZhongWeiXiang9的博客 484

es6的Promise对象详解

秋招已经进入了尾声,这两个月以来一直忙着找工作,没有时间看新东西,这几天得空将es6的Promise对象又细细的理解了一下,所以下来整理一下我对Promise对象以及用法的理解。什么是Promise?为什么要使用Promise? 当我们使用js的异步调用时通常习惯使用回调函数,这样的代码简单便于理解,但是当回调嵌套的时候就会造成代码混乱,不好梳理,比如:function fun1(arg1,fun

csdn_zsdf的博客 7141

ESP32搭配FT6236触摸屏:从芯片手册到完整I2C驱动代码的保姆级解析

本文详细解析了ESP32搭配FT6236触摸屏的I2C驱动开发过程,从芯片手册解读到完整代码实现。通过硬件架构分析、寄存器配置、I2C通信封装及触摸数据处理等步骤,提供了一套完整的驱动解决方案,帮助开发者快速掌握ESP32与触摸屏的交互技术。

weixin_29174385的博客 292

[仿真实战]FDTD Solutions 8.0:从零搭建薄膜光谱分析模型

本文提供了一份基于FDTD Solutions 8.0的薄膜光谱分析模型从零搭建实战指南。通过详细步骤,手把手教你创建玻璃基底与硅薄膜的几何结构、设置仿真区域与边界条件、配置光源与监视器,并最终计算反射率与透射率光谱。内容涵盖参数扫描与优化,旨在帮助用户快速掌握FDTD仿真在纳米光子学与薄膜光学设计中的核心应用。

defi6farmer的博客 499

【ES6】Promise对象详解

【ES6】Promise对象详解一、Promise对象的含义二、Promise对象的用法三、Promise对象的几个应用【重点】1、时间延迟函数2、图片异步加载 引言:ES6新增的Generato、Promise、async都与异步编程有关。这里我们讲述Promise对象。 一、Promise对象的含义   所谓Promise就是一个对象,用来传递异步操作的消息。它代表了...

十一月廿七风雨大作 6946

代付系统/代付系统源码/支付宝代付系统/API代付系统

简介: 其他站买的,没有做测试,源码是JAVA的,附带了安装文档,需要的拿无售后 源码下载地址https://www.skpan.cn/2QnIARSZDxG 代付系统/代付系统源码/支付宝代付系统/API代付系统 系统流程: 后台开通代理——开通商户——商户做代付(后台手工提交和 api 提交两种方式) 1、纯代付系统 2、支持个人支付宝全自动 3、支持单笔/批量/API接口方式代付 4、支持白名单、谷歌验证 5、收付款模式采用自动回调/自动转账 一、运营平台 商户管.

刀客源码网 5579

ES6——17. Promise对象

到了那个时候,Promise 的运行已经结束了,所以这个错误是在 Promise 函数体外抛出的,会冒泡到最外层,成了未捕获的错误。方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。这就是说,Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。事件的监听函数有两个参数,第一个是错误对象,第二个是报错的 Promise 实例,它可以用来了解发生错误的环境信息。方法,依次指定了两个回调函数。

chtazycdf的博客 1708

DeepSeek+即梦:AI视频创作从0到1全突破

本文为 DeepSeek 与即梦生成视频全攻略,从前期注册登录、熟悉工具界面及硬件网络准备入手,助读者开启 AI 视频创作。详细阐述利用 DeepSeek 构思脚本、即梦实现画面生成与静态图转动态视频的方法,包括提示词编写、参数调整等技巧。同时介绍后期合成音画、添加字幕特效及多平台适配要点,结合实战案例解析全流程。还分享进阶提示词优化、版权注意等避坑指南,为创作者提供从 0 到 1 的 AI 视频创作完整解决方案。

邓邓子的博客 8111

Pytest教程:Pytest插件原理

Pytest的插件系统是其强大功能的核心,它允许用户和开发者扩展和定制测试框架的行为。要深入理解Pytest插件的原理,我们需要从Pytest的架构和设计模式开始,然后深入到底层源码。

旦莫的博客 636

ES6 Promise 对象

ES6 Promise 对象

m0_52913477的博客 1414

问答式AI vs 智能体(Agent):它们有什么不同?

你肯定用过 ChatGPT 或文心一言——问它一个问题,它给你一个答案。AI Agent(AI智能体)。很多人搞不清楚:它们不都是"AI"吗?有什么区别?这篇文章用一个最简单的类比,彻底讲清楚这两者的本质差异。框架特点适合人群AutoGPT完全自主执行任务,链式思考开发者MetaGPT模拟团队协作,多角色分工开发者LangChain最流行的Agent开发框架开发者Dify可视化无代码搭建Agent非技术用户Coze(扣子)字节跳动出品,国内最易用普通用户WorkBuddy。

Johnny2004的专栏 447

JS | ES6新增对象 - Promise使用方法详解

Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有一下两个特点: * (1)对象的状态不受外界影响。 * (2)一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。

青春木鱼的博客 2825

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【ES6.0】- Promise对象

Promise是异步编程的一种解决方案,是一种javascript处理异步操作的一种常见方式。Promise是一种处理异步操作的设计模式,提供了一种更结构化,更可靠的方式来处理异步任务。

记录总结工作过往 867

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

es6中的promise对象

then中传了两个参数(这两个参数均为回调函数),then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。resolve函数的作用,将Promise对象的状态从“未完成”变成“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作。then方法是promise的最基本的方法,返回的是两个回调,一个成功的回调,一个失败的回调,实现过程如下。reject函数的作用是,在异步操作失败时调用,并将异步操作报出的错误,

2501_90207151的博客 765

【前端】ES6:Promise对象和Generator函数

这也是Promise这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。当一个回调函数嵌套一个回调函数的时候,就会出现一个嵌套结构,当嵌套的多了就会出现回调地狱的情况。Promise是异步编程的一种解决方案,比传统的解决方案回调函数,更合理和更强大。方法同样是将多个Promise实例,包装成一个新的Promise实例。p的状态由p1,p2,p3 决定,分成两种情况。

weixin_45980065的博客 1587

ES6深入—Module 与 Promise 对象

当异步操作执行成功后,会将异步操作结果作为参数传入 resolve 函数并执行,此时 Promise 对象状态从 pending 变为 fulfilled;失败则会将异步操作的错误作为参数传入 reject 函数并执行,此时 Promise 对象状态从 pending 变为 rejected。如果传入的参数为空的可迭代对象,则同步返回一个已完成(already resolved)状态的 Promise;一个模块就是一个独立的文件。示例,新建一个名为 userInfo.js 的文件,在其中写入以下代码。

2401_87288886的博客 889

【JavaScript 教程】ES6 中的 Promise对象 详解

【JavaScript 教程】ES6 中的 Promise对象 详解 1、Promise对象含义 promise是异步编程的一种解决方法。 所谓promise,简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从语法上说,promise是一个对象,从它可以获取异步操作的消息,promise提供了统一的API,各种异步操作都可以用同样的方法进行处理。 2、Promise 的状态 Promise有3种状态: Pending:进行中 Resolved(Fulfilled):已完成

菜鸟的后花园 3152

ES6 Promise相关用法详解

Promise是异步编程的一种解决方案,异步编程的历程经历了:回调函数和事件 ->Promise->。相较于传统的回调函数和事件,Promise了回调函数可能引发的,是有了进一步的。

qq_56427830的博客 1180

ES6标准-Promise对象

随后,我们调用promise.thn()回调函数,这是一个。构造函数接受一个函数作为参数,该函数的两个参数分别是。可以接收两个回调函数作为参数,第一个回调函数是。是异步编程的一种解决方案,比传统解决方案(这时,前一个回调函数,有可能返回的还是一个。函数,那么它们的参数会被传递给回调函数。,可以指定一组按照次序调用的回调函数。”的消息,用来演示异步操作的滞后性。,并不一定要提供,两个函数都接收。对象的状态发生变化,才会被调用。状态的回调函数,第二个参数是。状态后,再抛出错误,也不会被。

zheshiyangyang的博客 1745

JS ES6 Promise 之 Hello World

■前言最近学习VUE,涉及到了一些内容,都不了解,比如 Axios, Promise,所以,整理记录一下仅仅是一个【 简单 】的介绍,更多的内容,可以看看提供的文章链接,或是其他的资料。0.AxiosAxios,可以理解为ajax i/o system,这不是一种新技术,本质上还是对原生XMLHttpRequest的封装,可用于浏览器和nodejs的HTTP客户端,只不过它是基于Promise的,符合最新的ES规范。

sun0322 5219

ES6之Promise对象

在 ES6 中新增加了一种新的对象 —— Promise。 它的中文意思是 “承诺”,也就是答应别人的事就不会改变。而这个对象也如其名,一旦新建它就会立即执行,无法中途取消。 它从语法上来看,就是一个对象,它就是 用来传递异步操作的数据 。

小异常的博客 470

ES6 Promise对象

今天来给大家介绍的,是ES6中的新特性,也是前端开发中非常重要的一个特性——异步编程。异步编程想必大家早有耳闻,在js中最简单的异步方法是使用定时器做一个延迟操作。 而在ES6中引入了一个新的对象 Promise,它能够用来封装异步操作代码,并根据情况返回异步的状态,也是我们步入 Ajax的一个重要门槛。 ES6 Promise对象同步和异步的概念Promise 对象Promise 状态Promise 方法then方法 `Promise.prototype.then` 同步和异步的概念 在介绍前,我们再来简

weixin_47340917的博客 449

【ES6】Promise 对象

参考资料:阮一峰老师《ES6》电子书 一、Promise 的含义 1. Promise 是异步编程的一种解决方案。ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。 2.Promise,简单来说就是一个容器,里面保存着(通常是)一个异步操作的结果。 3.Promise对象有以下两个特点: (1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态...

Dora_5537的博客 493
上一篇: Vue填坑之路——Day4(项目)
下一篇: JavaScript高级程序设计——第3章 基本语法
扬扬羊
博客等级 码龄9年 11粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值