Promise对象深入理解
目录
基本用法
Promise 对象是一个构造函数,下面的例子生成一个 promise 对象
const promise = new Promise((resolve, reject)=>{
if(true){
resolve('异步操作成功了');
}else{
rejecte('异步操作失败了');
}
})
Promise 构造函数接受一个函数为参数,这个函数还接受两个参数,这两个参数都是函数
第一个函数用于异步成功,并将异步成功的结果以参数的形式传递出去,同时 promise 的状态改为 resolved
第二个函数用于异步失败,并将异步失败的结果以参数的形式传递出去,同时 promise 的状态改为 rejected
返回另一个 Promise 实例
通常情况 reject 函数返回的是异步错误信息,resolve 函数返回的是正常的理想值,而这个值也可以是另一个 Promise 实例,
如果返回的是另一个 Promise 的实例,那么这个实例将决定当前 Promise 实例的状态,自己本来的状态将失效
const p1 = new Promise(function (resolve, reject) {
// ...
});
const p2 = new Promise(function (resolve, reject) {
// ...
setTimeout( () => {resolve(p1),2000 }); // p1 的状态将决定 p2 的状态,而不是等到 2s 后
})
Promise.prototypeof.then
then 方法接受两个函数为参数,通常需要将 Promise 异步的结果作为参数传进去
第一个函数是 异步成功时(resolved)执行
第一个函数是 异步失败时(resolved)执行(可以不传该函数,改用 catch 方法监听异步的失败)
promise.then((res)=>{
console.log(res);
}, (rej)=>{
cnosole.log(rej);
})
then 方法会将新的 Promise 对象,因此可以链式调用。如果有返回值,那么返回值将作为参数传给新的 Promise 对象
promise.then((res)=>{
console.log(res);
return 'newPromise';
}, (rej)=>{
cnosole.log(rej);
}).then((res => {
console.log(res);
})
如果返回的新的 promise对象存在异步操作,例如返回一个 新的 Promise 实例对象,那么后面的 then 方法会等到这个promise状态发生改变时才执行
Promise.prototype.catch
上面有说到 then 方法接收两个函数为参数,分别是成功和失败时执行的,并且建议失败的函数改用 catch 方法
catch 可以实现 then 方法第二个参数的功能,但是它可以上代码跟直观
let a = 1;
let promise = new Promise(function(resolve, reject){
if(a==10){
resolve('成功');
}else{
reject('失败');
}
}); promise.then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
Promise.prototype.finally()
finally 方法用于指定 不管 Promise 对象最后状态如何,都会执行的操作。
promise
.finally(() => {});
Promise.resolve()
将现有对象转换为 promise 对象,分下面四种情况
1. 如果参数是 Promise 实例,那么 promise.resolve 将不做任何修改、原封不动地返回这个实例。
2. 如果参数是一个 thenable 对象。thenable 对象指的是具有 then 方法的对象,比如下面这个对象。Promise.resolve 方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); //
});
3. 如果参数是一个原始值,或者是一个不具有then方法的对象,则 Promise.resolve 方法返回一个新的 Promise 对象,状态为 resolved。下面代码生成一个新的 Promise 对象的实例p。由于字符串 Hello 不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是 resolved,所以回调函数会立即执行。Promise.resolve 方法的参数,会同时传给回调函数。
const p = Promise.resolve('Hello');
p.then(function (s){
console.log(s)
});
// Hello
4. Promise.resolve 方法允许调用时不带参数,直接返回一个 resolved 状态的 Promise 对象。需要注意的是,立即 resolve() 的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。
setTimeout(function () {
console.log('three');
}, 0); // 下一轮“事件循环”开始时执行,
Promise.resolve().then(function () {
console.log('two');
}); // 在本轮“事件循环”结束时执行
console.log('one');
// one
// two
// three
Promsie.reject()
同样也是将现有对象转换为 promise 对象,只不过 promise 对象的状态是 rejected
const p = Promise.reject('出错了');
Promise 的执行顺序
Promise 构造函数本身是同步执行的
then 方法会被放到微任务(microtask)队列中
setTimeout 定时器会放到宏任务(macrotask)队列中
当同步任务执行完后,微任务队列中的任务依次进入主线程执行,当微任务队列为空以后,宏任务队列中的任务依次进入主线执行
setTimeout(() => {
console.log(0);
},0)
new Promise(resolve => {
resolve(1);
Promise.resolve().then(t => {
console.log(2);
})
console.log(3);
}).then(t => {
console.log(t);
})
console.log(4);
//
//
//
//
//
现在分析上面的代码
1. 遇到定时器,将它放到宏任务队列中(这是第一个宏任务)
2. 同步执行构造函数
3. 在构造函数中遇到一个 then 方法,将他放到微任务队列中(这是第一个微任务)
4. console.log(3) 执行,打印出 3
5. 遇到第二个 then 方法,将他放到微任务队列的末尾
6. console.log(4) 执行,打印出 4
7. 读取微任务队列中的任务,依次打印出 2 1
8. 读取宏任务队列中的任务,打印出 0
Promise对象深入理解的更多相关文章
- ES6中Promise对象个人理解
Promise是ES6原生提供的一个用来传递异步消息的对象.它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多. Promise的状态: 既然是用来传 ...
- 谈谈 ES6 的 Promise 对象
https://segmentfault.com/a/1190000002928371 前言 开篇首先设想一个日常开发常常会遇到的需求:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作.一般 ...
- ES6的promise对象研究
ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...
- angularJS中的Promise对象($q)的深入理解
原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...
- 彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)
本文同步自我的个人博客: http://mly-zju.github.io/ 众所周知javascript语言的一大特色就是异步,这既是它的优点,同时在某些情况下也带来了一些的问题.最大的问题之一,就 ...
- 大白话理解promise对象
Promise 代表了未来某个将要发生的事件(通常是一个异步操作) Promise 是异步编程的解决方案,能够简化多层回调嵌套,代表了未来某个将要发生的事件.Promise是一个构造函数,本身有a ...
- ES6的promise对象应该这样用
ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的 ...
- JavaScript异步编程(1)- ECMAScript 6的Promise对象
JavaScript的Callback机制深入人心.而ECMAScript的世界同样充斥的各种异步操作(异步IO.setTimeout等).异步和Callback的搭载很容易就衍生"回调金字 ...
- Promise对象
1.Promise思想:每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程.这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用. ...
随机推荐
- ThinkPHP 静态页缓存
通过对ThinkPHP的学习,记录下静态页的缓存步骤,以便以后查阅: 1.配置配置文件/Admin/Conf/config.php代码如下: /*静态缓存*/ 'HTML_CACHE_ON'=> ...
- TortoiseSVN使用笔记
TortoiseSVN版本冲突详解 下列步骤展示了如何将分支A中的修改合并到分支B. 1.在分支B的本地副本目录中选择"合并(Merge)". 2.选择“合并一个版本范围(Me ...
- Block和inline元素对比
所有的HTML元素都属于block和inline之一.block元素的特点是:总是在新行上开始:高度,行高以及顶和底边距都可控制:宽度缺省是它的容器的100%,除非设定一个宽度<div>, ...
- Codeforces Round #376 (Div. 2) C. Socks —— 并查集 + 贪心
题目链接:http://codeforces.com/contest/731/problem/C 题解: 1.看题目时,大概知道,不同的袜子会因为要在同一天穿而差生了关联(或者叫相互制约), 其中一条 ...
- Gym - 100283F F. Bakkar In The Army —— 二分
题目链接:http://codeforces.com/gym/100283/problem/F F. Bakkar In The Army time limit per test 2 seconds ...
- ansible-playbook初始化服务器
hosts ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [test] 0.0.0.0 ansible_ssh_us ...
- 渲染树render tree
CSSOM树和DOM树连接在一起形成一个render tree,渲染树用来计算可见元素的布局并且作为将像素渲染到屏幕上的过程的输入. DOM树和CSSOM树连接在一起形成render tree . r ...
- Linux-awk和shell编程初步
1 awk 格式: awk -选项 '处理' 输入 awk -F : '{print $1}' file -F指定分隔符, 默认是空格 $1 分割后的第一部分 $0 获得所有部分 NF 表示以分隔符分 ...
- Windows_Program_Via_C_Translate_Win32编程的背景知识/基础知识_包括基本输入输出机制介绍
Some Basic Background Story of The Win32 APIs Win32 API背景故事/背景知识 The Win32 application programming i ...
- bzoj 4668 冷战——并查集结构
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4668 不路径压缩,维护并查集的树的结构,查询链上最大值.按秩合并就可以暴爬. #includ ...