ES6之Promise对象学习——8个例子学会Promise
目录
- Promise 立即执行
- Promise 三种状态
- Promise 不可逆性
- 链式调用
- Promise.then()回调异步性
- Promise中的异常
- Promise.resolve()
- resolve vs reject
一、Promise立即执行
代码:
var p = new Promise(function(resolve, reject){
console.log('create a promise');
resolve('success');
});
console.log('after new Promise');
p.then(
function(val){
console.log(val);
},
function(err){
console.log(err);
}
)
执行结果:
* create a promise
* after new Promise
* success
解析:
Promise对象表示未来要发生的事情,但是在创建 new Promise(function(){}) 时,其中的匿名函数是会被立即执行的,只是其中的代码可以是异步执行的{ example: 体现在 p.then()会被异步执行,但是一定要 这样调用一次resolve(‘success’),才会执行p.then() }。
二、Promise三种状态
代码:
var p1 = new Promise(function(resolve, reject){
resolve(1);
});
var p2 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve(2);
}, 500);
});
var p3 = new Promise(function(){
setTimeout(function(){
resolve(3);
}, 500);
});
console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(function(){
console.log(p2);
}, 1000);
setTimeout(function(){
console.log(p3);
}, 1000);
p1.then(function(val){
console.log(val);
});
p2.then(function(val){
console.log(val);
});
//此处的catch方法,等价于then(fn1, fn2)方法中的fn2。 当resolve()时,执行fn1;当reject时,执行fn2。
p3.catch(function(err){
console.log(err);
});
执行结果:
Promise { 1 }
Promise { <pending> undefined }
Promise { <pending> undefined }
1
2
3
Promise { <resolved> 2 }
Promise { <rejected> 3 }
解析:
Promise的内部实现是一个状态机,Promise有3钟状态:pending、resolved、rejected。
*当Promise刚刚创建完成时,处于pengding。
*当Promise中的函数执行resolve方法后,由之前的pending –> resolved
*当Promise中的函数不执行resolve,而是执行了reject方法,那会由之前的pending –> rejected
三、Promise 状态的不可逆性
代码:
var p1 = new Promise(function(resolve, reject){
resolve('success1');
resolve('success2');
});
var p2 = new Promise(function(resolve, reject){
resolve('success3');
reject('reject');
});
p1.then(function(val){
console.log(val);
});
p2.then(function(val){
console.log(val);
});
执行结果:
success1
success
解析:
Promise的状态一定确定下来时,Promise的状态和值就固定下来了,不论如何调用 resolve() 和 reject() ,都不能改变它的值和状态。
四、链式调用
代码:
var p = new Promise(function(resolve, reject){
resolve(1);
});
p.then( //第1个then
function(val){
console.log(val);
return val*2;
}
).then( //第2个then
function(val){
console.log(val);
}
).then( //第3个then
function(val){
console.log(val);
return Promise.resolve('resolve');
}
).then( //第4个then
function(val){
cosnole.log(val);
return Promise.reject('reject');
}
).then( //第5个then
function(val){
console.log('resolve=' + val);
}, function(err){
console.log('reject=' + err);
}
);
执行结果:
1
2
undefined
resolve
reject=reject
解析:
Promise对象的then方法返回一个新的Promise对象,因此可以通过链式调用then方法。then方法接收2个参数,第一个参数是Promise执行成功时的回调;第二个是Promise执行失败的回调。2个函数只有一个被调用,函数的返回值将被用作创建then返回的Promise对象,这2个参数的返回值可以是一下3种情况中的一种:
* return 一个同步值 或者 undefined (当没有一个有效的返回值时,默认返回undefined,then方法将返回一个resolved状态的Promise对象,Promise对象的值就是这个返回值。)
* return 另一个Promise, then方法将根据这个Promise的状态和值创建一个新的Promise对象返回。
* throw 一个同步异常,then方法将返回一个rejected状态的Promise和该异常值。
所以 第一个then返回值是:2;第二个then没有返回值,默认返回undefined;第三个then会返回一个状态是resolved值是resolve的新Promise对象;第四个then会返回一个状态为rejected值为reject的新Promise对象;第五个then因为执行失败,会走第二个函数。
五、Promise.then()回调异步性
代码:
var p1 = new Promise(function(resolve, reject){
resolve('success');
});
p1.then(function(val){
console.log(val);
});
console.log("which one is called first ?");
执行结果:
which one is called first ?
success
解析:
Promise接收的函数是同步执行的,但是then中的回调函数的执行则是异步的。
因此‘sucees’会在后面输出。
为什么then会优先于定时器先执行?
*是因为等待队列(或者说是任务队列)其实是分为两个: macrotask 和 microtask;promise是存放在microtasks中,而定时器是存放在macrotasks中,但是在每次”事件循环”后会先执行microtask中的内容,并且当这些 microtask 执行结束后还能继续添加 microtask 一直到真个 microtask 队列执行结束(这也就是所说的”拆箱”),直到当前microtask执行结束之后,才会执行macrotask中的任务,并且往下进行”事件循环”所以才会出现如上代码输出的结果。
六、Promise中的异常
代码:
var p1 = new Promise(function(resolve, reject){
foo.bar();//异常执行
resolve(1);
});
p1.then(
function(val){
console.log('p1 then val:' + val);
}, function(err){
console.log('p1 then err:' + val);
}
).then(
function(val){
console.log('p1 then val:' + val);
}, function(err){
console.log('p1 then err:' + val);
}
);
var p2 = new Promise(function(resolve, reject){
resolve(2);
});
p2.then(
function(val){
console.log('p2 then val:' + val);
foo.bar();//异常执行
}, function(err){
console.log('p2 then err:' + val);
}
).then(
function(val){
console.log('p2 then val:' + val);
}, function(err){
console.log('p2 then err:' + val);
return 1;
}
).then(
function(val){
console.log('p2 then val:' + val);
}, function(err){
console.log('p2 then err:' + val);
}
);
执行结果:
p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then value: undefined
p2 then err: ReferenceError: foo is not defined
p2 then value: 1
解析:
Promise中的异常有then参数中的第二个回调函数 (Promise执行失败的回调) 处理,异常信息作为Promise的值。异常一旦得到处理, then后返回的后续Promise对象恢复正常,并会被Promise执行成功的回调函数处理。 另外需要注意:p1、p2多级then的回调函数是交替执行的,这正是由于Promise then回调的异步性决定的。
七、Promise中的异常
代码:
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(p1);
var p3 = new Promise(function(resolve, reject){
resolve(1);
});
var p4 = new Promise(function(resolve, reject){
resolve(p1);
});
console.log( p1 === p2 );
console.log( p1 === p3 );
console.log( p1 === p4 );
console.log( p3 === p4 );
p4.then(function(val){
console.log('p4=' + val);
});
p2.then(function(val){
console.log('p2=' + val);
});
p1.then(function(val){
console.log('p1=' + val);
});
执行结果:
true
false
false
false
p2=1
p1=1
p4=1
解析:
Promise.resolve(…)可以接收一个值或者是一个Promise对象作为参数。
* 当参数为普通值时,他返回一个resolved状态的Promise对象,对象的值就是这个参数。
* 当参数为一个Promise对象时,会直接返回这个Promise对象。
* 使用new创建的Promise对象是一个全新的对象。
所以p1===p2,所以p1不等于p3,p4。
p4之所以是最先调用最后输出是因为:
p4接收的是一个promise对象p1,resolve会对p1进行’拆箱’,获取p1的值。
八.resolve vs reject
代码:
var p1 = new Promise(function(resolve, reject){
resolve(Promise.resolve('resolve'));
});
var p2 = new Promise(function(resolve, reject){
resolve(Promise.reject('reject'));
});
var p3 = new Promise(function(resolve, reject){
reject(Promise.resolve('resolve'));
});
p1.then(
function(val){
console.log('p3[val]=' + val );
},
function(err){
console.log('p3[err]=' + err );
}
)
p2.then(
function(val){
console.log('p3[val]=' + val );
},
function(err){
console.log('p3[err]=' + err );
}
)
p3.then(
function(val){
console.log('p3[val]=' + val );
},
function(err){
console.log('p3[err]=' + err );
}
)
执行结果:
* p3[err]=[object Promise]
* p3[val]=resolve
* p3[err]=reject
解析:
* resolve 可以’拆箱’Promise对象; reject不能’拆箱’Promise对象。
原文地址:https://juejin.im/post/597724c26fb9a06bb75260e8
ES6之Promise对象学习——8个例子学会Promise的更多相关文章
- Javascript Promise对象学习
ES6中的Promise对象 var p = new Promise(function(resolve, reject){ window.setTimeout(function(){ console. ...
- JS Promise对象学习
Promise对象的三个状态 pending(进行中) fulfilled(已成功) rejected(已失败) Promise代表一个异步操作,对象的状态一旦改变,就不会再改变 Promise构造函 ...
- ES6的promise对象应该这样用
ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的 ...
- ES6的promise对象研究
ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...
- ES6 Promise 对象
Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Pro ...
- ES6的Promise对象
http://es6.ruanyifeng.com/#docs/promise Promise 对象 Promise 的含义 基本用法 Promise.prototype.then() Promise ...
- ES6的新特性(15)——Promise 对象
Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了 ...
- ES6之Promise对象
创建Promise对象 function getHtml(url) { return new Promise((resolve, reject) => { let xhr = new XMLHt ...
- 通过一道笔试题浅谈javascript中的promise对象
因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...
随机推荐
- 从前端看JavaWeb软件工程中的解耦合
以下为作者备忘,详情请看 http://www.cnblogs.com/feichengwulai/articles/3412946.html http://blog.csdn.net/piantou ...
- EasyDarwin开源流媒体服务器支持basic基本认证和digest摘要自定义认证
本文转自EasyDarwin开源团队成员的博客:http://blog.csdn.net/ss00_2012/article/details/52330838 在前面<EasyDarwin拉流支 ...
- jquery 使用ajax,正常返回后,不执行success的问题
背景: 在使用到jQuery的ajax时,如果指定了dataType为json,老是不执行success回调,而是执行了error回调函数. 原因: 然后继续下载了几个jquery版本,如1.3.2, ...
- SpringBoot-(7)-基于Web,JDBC,MySql,Druid,MyBatis整合创建SpringBoot项目
1 打开Spring Initializr 如果Project SDK为空,手动指定下JDK SDK路径 2, 填写Group和Artifact 3,选择依赖 选择Web,MySQL,JDBC,MyB ...
- some base knowledge
har类型的长度被定义为一个8位字节,这很简单. short类型的长度至少为两字节.在有些计算机上,对于有些编译程序,short类型的长度可能为4字节,或者更长. int类型是一个整数的“自然”大小, ...
- CoreData使用
1.如果想创建一个带有coreData的程序,要在项目初始化的时候勾选中 2.创建完成之后,会发现在AppDelegate里多出了几个属性,和2个方法 <span style="fon ...
- HDU 1878(1Y) (判断欧拉回路是否存在 奇点个数为0 + 一个联通分量 *【模板】)
欧拉回路 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 通用双向链表的设计(参考Linux系统中的实现)
通常我们设计设计链表都是将数据域放在里面,这样每次需要使用链表的时候都需要实现一个链表,然后重新实现它的相关操作,这里参考Linux系统中的设计实现了一个通用的双向链表,只需要在你的结构里面有一个这个 ...
- SQL Server 2008将数据导出为脚本 [SQL Server]
之前我们要将一个表中的数据导出为脚本,那么只有在网上找一个导出数据的Script,然后运行就可以导出数据脚本了.现在在SQL Server 2008的Management Studio中增加了一个新特 ...
- Oracle数据库当前连接数、最大连接数的查询与设置
在开发过程中Oracle数据库有时候连得上,有时候又连不上,提示如下异常“ORA-12519: TNS:no appropriate service handler found 解决”,可能是数据库上 ...