ES6新特性六:promise对象实例详解

发布时间 - 2026-01-11 00:45:42    点击率:

本文实例讲述了ES6新特性之promise对象。分享给大家供大家参考,具体如下:

1. promise 介绍

它是一个对象,也就是说与其他JavaScript对象的用法,没有什么两样;其次,它起到代理作用(proxy),充当异步操作与回调函数之间的中介。它使得异步操作具备同步操作的接口,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套。

它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程。这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用。

异步操作f1返回一个Promise对象,它的回调函数f2写法如下

(new Promise(f1)).then(f2);

2. promise 对象的三种状态

① 异步操作未完成(pending)
② 异步操作已完成(resolved)
③ 异步操作失败(rejected)

3. 工作过程

Promise对象使用then方法添加回调函数。then方法可以接受两个回调函数,第一个是异步操作成功时(变为resolved状态)时的回调函数,第二个是异步操作失败(变为rejected)时的回调函数(可以省略)。一旦状态改变,就调用相应的回调函数,这两个回调函数都接受异步操作传回的值作为参数

promise.then(
 console.log,
 console.error
);

4. then 的链式使用

① 首先then方法返回的一个新的promise对象,因此可以采用链式写法。

② then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。

③ 如下,promise的状态一旦变为resolved,就依次调用后面每一个then指定的回调函数,每一步都必须等到前一步完成,才会执行。最后一个then方法的回调函数console.log和console.error,用法上有一点重要的区别。console.log只显示回调函数step3的返回值,console.error可以显示step1、step2、step3之中任意一个发生的错误,Promises对象的错误有传递性。

promise
 .then(step1)
 .then(step2)
 .then(step3)
 .then(
  console.log,
  console.error
 );

5. promise 对象的使用

var promise = new Promise(function(resolve, reject) { // promise的构造函数,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject
 // 异步操作的代码
 if (/* 异步操作成功 */){
  resolve(value);//将异步的操作结果作为参数传递出去
 } else {
  reject(error);
 }
});

其中resolve和reject它们是两个函数,由JavaScript引擎提供,不用自己部署。

resolve函数的作用:将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用:将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

① 下面是一个用Promise对象实现的Ajax操作的例子

var getJSON = function(url) {
 var promise = new Promise(function(resolve, reject){
  var client = new XMLHttpRequest();
  client.open("GET", url);
  client.onreadystatechange = handler;
  client.responseType = "json";
  client.setRequestHeader("Accept", "application/json");
  client.send();
  function handler() {
   if (this.readyState !== 4) {
    return;
   }
   if (this.status === 200) {
    resolve(this.response);//会将参数传递给回调函数
   } else {
    reject(new Error(this.statusText));
   }
  };
 });
 return promise;
};
getJSON("/posts.json").then(function(json) {
 console.log('Contents: ' + json);
}, function(error) {
 console.error('出错了', error);
});

② resolve函数的参数除了正常的值以外,还可能是另一个Promise实例,即一个异步操作的结果是返回另一个异步操作。

var p1 = new Promise(function (resolve, reject) {
 // ...
});
var p2 = new Promise(function (resolve, reject) {
 // ...
 resolve(p1);
})

6.Promise.prototype.catch()

① 一个 Promise 对象,如果异步操作抛出错误,状态就会变为Rejected,就会调用catch方法指定的回调函数,处理这个错误。

promise.then(function(posts) {
 // ...
}).catch(function(error) {
 // 处理 getJSON 和 前一个回调函数运行时发生的错误
 console.log('发生错误!', error);
});

② 另外,then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。

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

③ 另外两种写法

// 写法一
var promise = new Promise(function(resolve, reject) {
 try {
  throw new Error('test');
 } catch(e) {
  reject(e);
 }
});
promise.catch(function(error) {
 console.log(error);
});
// 写法二
var promise = new Promise(function(resolve, reject) {
 reject(new Error('test'));//reject方法的作用,等同于抛出错误
});
promise.catch(function(error) {
 console.log(error);
});

④ Promise 在resolve语句后面再抛出错误不会被捕获。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

var 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

7 Promise.all()

参数为Promise 对象的数组;将多个Promisre 对象包装成一个新的Promise 对象,如果数组中不是Promise 对象,就会自动调用 Promise.resolve方法,将参数转为Promise实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例)

var p = Promise.all(promises).then(function (posts) {
 // ...
}).catch(function(reason){
 // ...
});

① 只要promises之中有一个状态变为rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
② 如果全部都变为resolved;此时 promises 数组中所有对象的返回值组成一个数组,传递给p的回调函数。

8 Promise.resolve()

将现有对象转为 Promise对象,Promise.resolve方法就起到这个作用。

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

① 参数为Priomise 对象,Promise.resolve() 不做任何处理。
② 参数是一个具有 then 方法的对象:Promise.resolve方法会将这个对象转为Promise对象,然后就立即执行thenable对象的then方法。

let thenable = {
 then: function(resolve, reject) {
  resolve(42);
 }
};
let p1 = Promise.resolve(thenable);//p1为一个状态已经是resolved 的promise对象.
p1.then(function(value) {
 console.log(value); // 42
});

③ 参数不是具有then方法的对象,或根本就不是对象

该参数变为生成的 Promise 对象的 resolve() 的参数。

var p = Promise.resolve('Hello');//Hello 会传递给 p 的resolve()
p.then(function (s){
 console.log(s)
});
// Hello

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


# ES6  # 新特性  # promise对象  # ES6中非常实用的新特性介绍  # JavaScript ES6的新特性使用新方法定义Class  # JavaScript中的Reflect对象详解(ES6新特性)  # 深入浅出ES6新特性之函数默认参数和箭头函数  # 简单谈谈ES6的六个小特性  # ES6新特性之Symbol类型用法分析  # ES6(ECMAScript 6)新特性之模板字符串用法分析  # ES6新特性之变量和字符串用法示例  # ES6新特性之模块Module用法详解  # ES6新特性之字符串的扩展实例分析  # ES6新特性二:Iterator(遍历器)和for-of循环详解  # ES6新特性七:数组的扩充详解  # ES6新特性八:async函数用法实例详解  # ES6新特性之类(Class)和继承(Extends)相关概念与用法分析  # 让微信小程序支持ES6中Promise特性的方法详解  # ES6新特性:使用export和import实现模块化详解  # es6新特性之 class 基本用法解析  # ES6 13个新特性总结  # 回调  # 就会  # 链式  # 第一个  # 抛出  # 是一个  # 未完成  # 返回值  # 第二个  # 并将  # 会将  # 有一个  # 即从  # 组中  # 都是  # 也会  # 多个  # 才会  # 两种  # 上有 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  在线教育网站制作平台,山西立德教育官网?  Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  如何用5美元大硬盘VPS安全高效搭建个人网站?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  移动端脚本框架Hammer.js  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  微信小程序 五星评分(包括半颗星评分)实例代码  Laravel如何实现本地化和多语言支持?(i18n教程)  javascript中的try catch异常捕获机制用法分析  js实现点击每个li节点,都弹出其文本值及修改  公司门户网站制作流程,华为官网怎么做?  香港服务器建站指南:免备案优势与SEO优化技巧全解析  js实现获取鼠标当前的位置  微信小程序 wx.uploadFile无法上传解决办法  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  JS碰撞运动实现方法详解  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  JavaScript实现Fly Bird小游戏  如何在Ubuntu系统下快速搭建WordPress个人网站?  Laravel Debugbar怎么安装_Laravel调试工具栏配置指南  如何在搬瓦工VPS快速搭建网站?  如何用PHP工具快速搭建高效网站?  Python并发异常传播_错误处理解析【教程】  Win11怎么设置默认图片查看器_Windows11照片应用关联设置  个人网站制作流程图片大全,个人网站如何注销?  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  Android实现代码画虚线边框背景效果  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  Laravel如何使用Sanctum进行API认证?(SPA实战)  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  Laravel storage目录权限问题_Laravel文件写入权限设置  Laravel定时任务怎么设置_Laravel Crontab调度器配置  Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程  详解Android中Activity的四大启动模式实验简述  Laravel怎么使用Intervention Image库处理图片上传和缩放  node.js报错:Cannot find module 'ejs'的解决办法  制作公司内部网站有哪些,内网如何建网站?  详解jQuery停止动画——stop()方法的使用  郑州企业网站制作公司,郑州招聘网站有哪些?  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  如何在云服务器上快速搭建个人网站?  WordPress 子目录安装中正确处理脚本路径的完整指南  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议