JavaScript中对Promise对象的理解
注意单词对应的翻译,有助于理解整个模式
promise: 承诺
pending: 待定
settled: 定了
resolve(d): (已)解决
reject(ed): (已)拒绝
onFulfilled: 已履行(事件)
onRejected: 已拒绝(事件)
then: 然后,接下来
catch: 捕获
race: 赛跑
future: 未来(值)
thenable:可then的(有then属性的)
一.Promise是什么
一套异步操作处理机制, Promise A+ 是规范,jQuery、ES2015、q的promise都是对该规范的一种实现
二.Promise有什么特点
更容易控制异步操作的执行顺序
可以在一系列异步操作中,灵活地处理错误
支持链式调用,好写
能够消除回调金字塔,好看
三.Promise有什么用
实现串行任务队列
实现串行任务管道
处理运行时才能确定执行顺序的串行任务
(篇幅限制,具体适用场景以后再展开)
四.Promise类型
内部属性[[PromiseStatus]]/[[PromiseValue]]
[[PromiseStatus]]:pending(待定) | resolved(已解决) | rejected(已拒绝)
后两个统称 settled
(定了), pending
是初始状态,如果 new Promise(func)
后, func
中的 resolve
和 reject
都还没有执行,此时 status=pending
[[PromiseValue]]:undefined | resolve/reject的参数 | Promise.resolve/reject的!thenable参数 | onFulfilled/onRejected的返回值
当 then
被调用时,该值会被传给 then
的 onFulfilled
或 onRejected
,如果 resolve
和reject
始终没有执行,那么 then
的 onFulfilled
和 onRejected
也始终不会执行
构造器参数resolve/reject
resolve(解决)
执行 resolve
后,触发 then
的 onFulfilled
回调,并把 resolve
的参数传递给 onFulfilled
reject(拒绝)
执行 reject
后,触发 then
| catch
的 onRejected
回调,并把 reject
的参数传递给 onRejected
注意 :如果紧跟的 then
没有声明 onRejected
回调,则传给下一个 then
| catch
的 onRejected
,还没有,接着传…如果走到头都没有,则报错Uncaught (in promise) Error:xxx
特殊的 :如果 resolve
的参数是Promise对象,且该Promise对象后面没有跟 then
,则该对象的 resolve
/ reject
会触发外层Promise对象后续的 then
的 onFulfilled/onRejected
五.基本语法
1.创建Promise对象
创建Promise的基本语法如下:
// 创建
var promise = new Promise(function(resolve, reject) {if (/*...*/) {resolve(data);}else {reject(new Error('error occurs'));}
});
// 使用
// then
promise.then(function(future) {// ...
}, function(error) {// ...
});
// catch
promise.catch(function(error) {// ...
});
注意 : new Promise(func)
时, func
会 立即执行 (不像generator只声明不执行),执行过程中遇到 resolve()
装没看见(P.S.简单理解为装没看见,解释见注释),遇到 reject()
立即抛出错误,对比例子如下:
new Promise(function(resolve, reject) {console.log('#1');resolve(1);console.log('#2');
});
// => #1 #2 不报错(遇到resolve装没看见)
// 其实内部属性[[PromiseStatus]]和[[PromiseValue]]都变了,但没有then提供的onFulfilled回调,看不到效果
new Promise(function(resolve, reject) {console.log('#1');reject(new Error('reject'));console.log('#2');
});
// => #1 #2 报错:Uncaught (in promise) Error: reject(…)
// 因为后面没有then/catch提供的onRejected回调,异常没有被消费掉
P.S. reject
的参数可以是任意类型的,但一般都传入 Error
对象表示错误原因
2.Promise.prototype.then(onFulfilled, onRejected) 然后
给 promise
添加 onFulfilled/onRejected
回调handler,当 promise
的 resolve/reject
执行时触发对应handler
注意 :用 promise.then
添加回调函数时,如果 promise
已经处于 fulfilled
或 rejected
状态,那么相应的方法将会被 立即调用
返回一个Promise对象 (链式调用有戏),可以简单理解为:
1.如果触发了 onFulfilled
,则该对象的[[PromiseValue]]=onFulfilled的返回值,[[PromiseStatus]]=resolved
new Promise(function(resolve, reject) {resolve(2);
}).then(function(future) {return future * 2;
}, onRejected).then(onFulfilled, onRejected);
// onFulfilled拿到了4
2.如果触发了onRejected,则该对象的[[PromiseValue]]=onRejected的返回值,[[PromiseStatus]]=resolved
特别注意 :返回对象的状态是 resolved
,而 不是 rejected
new Promise(function(resolve, reject) {reject(2);
}).then(null, function(err) {return err * 2;
}).then(onFulfilled, onRejected);
// 还是onFulfilled拿到了4,而不是onRejected
P.S.实际上[[PromiseValue]]=undefined, [[PromiseStatus]]=pending,但仍将按照上述状态来执行
3.Promise.prototype.catch(onRejected) 捕获
等价于 then(null, onRejected)
,返回一个Promise对象,可以简单理解为:
1.如果触发了onReject,则返回对象的[[PromiseValue]]=onReject的返回值, [[PromiseStatus]]=resolved
2.如果onReject始终没有触发,则装作没看见catch,直接返回原Promise对象
var p = new Promise(function(resolve, reject) {resolve(2);
}).catch(function() {console.log('onRejected');return false;
});
p.then(onFulfilled, onRejected);
// onFulfilled拿到了2,catch没有任何影响
P.S.实际上[[PromiseValue]]=undefined, [[PromiseStatus]]=pending,但仍将按照上述状态来执行
4.Promise.all(iterable)
返回Promise对象,当 iterable
中所有 promise
都 resolve
后,触发 onFulfilled
,遇到第一个否定 promise
就立即退出,并触发 onRejected
//1.全肯定集合,触发onFulfilled,传入的参数是集合中所有promise的[[PromiseValue]]组成的数组
Promise.all([getPromise(), getPromise()]).then(onFulfilled, onRejected);//2.全否定集合,遇到第一个否定promise就退出,触发onRejected,传入的参数是该promise的[[PromiseValue]]
// Promise.all([getPromise(true), getPromise(true)]).then(onFulfilled, onRejected);// 3.一般集合,同上
// Promise.all([getPromise(true), getPromise()]).then(onFulfilled, onRejected);
P.S.all,要么全都正常完成,要么因错误中断,全都停下来
5.Promise.race(iterable) 赛跑
返回Promise对象,当 iterable
中有任意一个 promise
被 resolve
后就立即退出,并触发 onFulfilled
,遇到否定 promise
就立即退出,并触发 onRejected
// 1.全肯定集合,遇到第一个肯定promise就退出,触发onFulfilled,传入的参数是该promise的[[PromiseValue]]
// Promise.race([getPromise(), getPromise()]).then(onFulfilled, onRejected);
// 2.全否定集合,遇到第一个否定promise就退出,触发onRejected,传入的参数是该promise的[[PromiseValue]]
// Promise.race([getPromise(true), getPromise(true)]).then(onFulfilled, onRejected);
// 3.一般集合,同上
// Promise.race([getPromise(true), getPromise()]).then(onFulfilled, onRejected);
P.S.“赛跑”,不论结果是肯定还是否定,只要最快的
6.Promise.resolve(value) 解决
1.如果 value
是 promise
,则把 promise
中 resolve/reject
的参数传递给对应的 onFulfilled/onRejected
Promise.resolve(getPromise()).then(onFulfilled, onRejected);
// onFulfilled拿到resolve的参数
Promise.resolve(getPromise(true)).then(onFulfilled, onRejected);
// onRejected拿到reject的参数
2.如果 value
是thenable对象(有 then
属性的对象),就会把 obj
包装成Promise对象,该对象的 then
就是 obj.then
Promise.resolve({then: function(onFulfilled, onRejected) {// onFulfilled(1);onRejected(new Error('obj.then err'));console.log('obj.then');}
}).then(onFulfilled, onRejected);
3.如果 value
是!thenable值,会把该值包装成Promise对象,该对象的[[PromiseValue]]=value, [[PromiseStatus]]=resolved,所以调用then方法时,onFulfilled将会接收到这个值
Promise.resolve(1).then(onFulfilled, onRejected);
// onFulfilled拿到1
7.Promise.reject(reason) 拒绝
会把 reason
包装成Promise对象,该对象的[[PromiseValue]]=reason, [[PromiseStatus]]=rejected,所以调用 then
方法时, onRejected
将会接收到这个值
注意 :这里没有thenable/!thenable的区别,一视同仁:
// 1.!thenable onRejected将拿到Error对象
Promise.reject(new Error('static reject')).then(onFulfilled, onRejected);
// 2.promise onRejected将拿到被包起来的肯定Promise对象
// 该对象的[[PromiseValue]]=promise, [[PromiseStatus]]=rejected
Promise.reject(getPromise()).then(onFulfilled, onRejected);
// 3.thenable onRejected将拿到{then: xxx}
Promise.reject({then: function(onFulfilled, onRejected) {console.log('obj.then');}
}).then(onFulfilled, onRejected);
完整的测试DEMO:promise实例
六.高级用法
配合生成器(
generator
)配合
async/await
转载于http://www.tuicool.com/articles/uQ3uEzE,更多详情可以关注
JavaScript中对Promise对象的理解相关推荐
- 浅析JaveScript中的Promise对象 暮雨清秋
前言 本文旨在简单讲解一下javascript中的Promise对象的概念,特性与简单的使用方法.并在文末会附上一份符合PromiseA+规范的Promise对象的完整实现. 注:本文中的相关概念均基 ...
- 【JavaScript 教程】ES6 中的 Promise对象 详解
[JavaScript 教程]ES6 中的 Promise对象 详解 1.Promise对象含义 promise是异步编程的一种解决方法. 所谓promise,简单说是一个容器,里面保存着某个未来才会 ...
- Javascript 在循环中使用Promise对象
先看一个生成Promise对象的方法 function createPromise() {var promise;promise = new Promise(function(resolve, rej ...
- javascript中浅拷贝和深拷贝的理解
javascript中浅拷贝和深拷贝的理解 什么是拷贝? 简单地说就是复制,对数据的复制 浅拷贝:改变拷贝者的值,被拷贝者的值也会变化 深拷贝:改变拷贝者的值,被拷贝者的值不会变化 由于基本数据类型是 ...
- 选择嵌套_如何优雅地在JavaScript中访问嵌套对象
在JavaScript中访问嵌套对象 以超酷的方式安全地访问JavaScript中的嵌套对象 JavaScript是惊人的,我们都知道.但是JavaScript中的一些东西真的很奇怪,它们让我们大开眼 ...
- 12.在JavaScript中的事件模型如何理解?
一.事件与事件流 javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件.鼠标事件.自定义事件等 由于DOM是一个树结构,如果在 ...
- Javascript基础与面向对象基础~第四讲 Javascript中的类对象
今天来说JS中如何实现类(class),事实上本应该昨天晚上写的,可我失言了,在些说一声"抱歉"!JS中的类是JS面向对象的基础,也是我最拿手的东西,你写的代码能否提高一个层次,一 ...
- 【从0到1学Web前端】javascript中的ajax对象(一)
[从0到1学Web前端]javascript中的ajax对象(一) 如今最流行的获取后端的(浏览器从server)数据的方式就是通过Ajax了吧.今天就来具体的来学习下这个知识吧.假设使用ajax来訪 ...
- php节点对象,JavaScript_JavaScript中访问节点对象的方法有哪些如何使用,JavaScript中访问节点对象的方法 - phpStudy...
JavaScript中访问节点对象的方法有哪些如何使用 JavaScript中访问节点对象的方法有哪些? var obj = document.getElementById('fdafda'); va ...
- JavaScript id_好程序员web前端分享Javascript中函数作为对象
好程序员web前端分享Javascript中函数作为对象,Javascript赋予了函数非常多的特性,其中最重要的特性之一就是将函数作为第一型的对象.那就意味着在javascript中函数可以有属性, ...
最新文章
- 【干货】CNN与Transformer的强强联合!谷歌最新开源BoTNet,ImageNet达84.7%准确率
- 接上篇-找虚拟主机过程
- serv-u 自定义html,Serv-U架设教程_Serv-U使用教程图文版
- How to include html native content to UI5 page - 直接在xml view里添加html namespace
- Python个人项目--豆瓣图书个性化推荐
- 软件工程 团队作业 #9
- Qt4_十六进制微调框
- java日志系统简介: 从tomcat大量打印debug日志说起
- 巧用层次坐标解决统计图分类轴与系列取值
- 沃谈小知识|可“防拆”的远程锁机
- 象棋马走日步数计算流程图
- C++11(及现代C++风格)和快速迭代式开发 -- 刘未鹏
- Resnet网络中数字的含义以及连接方式
- LINUX下简单实现ISP图像处理从RAW到RGB,BMP算法、RGB到JPEG库的使用(一)
- 抠图应用程序设计(一)——GrabCut算法的实现
- windows服务器系统发展史,从1.0到Win10:Windows操作系统进化史
- Python改变时间颗粒度
- Invalid drive错误的解决方案
- 从古代文学到云端技术
- Flink随堂笔记:Connectors概述