关于Promise的总结
来源:互联网 发布:nginx 时间函数 编辑:程序博客网 时间:2024/04/28 23:24
Promise是抽象异步处理对象以及对其进行各种操作的组件,它的功能是可以将复杂的异步处理轻松的模式化
创建Promise对象的方法
创建对象的方法
1.new Promise(fn)返回一个Promise对象
2.在fn
中指定异步等处理
- 处理结果正确的时候,调用resolve(处理结果值)
- 处理结果错误的时候,调用reject(Error对象)
3.使用 promise.then() 实例方法,对Promise的实例对象设置其在resolve/reject时调用的回掉函数(一次调用),当然如果只想处理异常可以采用 promise.catch(onRejected)或者promise.then(undefined, onRejected)
举例
调用asyncFunction的时候返回的是一个Promise的实例对象,所以在调用完asyncFunction的时候使用了then,设置了成功与失败时候的回掉函数
function asyncFunction() { return new Promise(function(resolve, rejecct) { setTimeout(function() { resolve('Hello World'); }, 16); });}asyncFunction().then(function(value) { console.log("Fulfilled", value);}).catch(function(error) { console.log("error", error);});
Promise的实例对象的三种状态
通过new Promise返回的Promise对象,有以下三种状态:
- has-resolution-Fulfilled,resolve(成功)时,会调用onFulfilled
- has-rejection - Rejected,reject(失败)时,会调用onRejected
- unresolved-pending,既不是resolve也不是reject的状态,也就是Promise对象刚被创建后的初始化状态等
Fulfilled和Rejected这两个中的任一状态都可以表示为Settled(不变的)。
创建XHR的Promise对象
function getURL(url) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open("get", url); xhr.onload = function() { if(xhr.status == 200) { resolve(xhr.responseText); }else { reject("状态错误"); } }; xhr.onerror = function() { reject("出错"); } xhr.send(); });}//https://httpbin.org/status/500//https://httpbin.org/get getURL('https://httpbin.org/get').then((value) => { console.log(value);}).catch((error) => { console.log(error);});
创建Promise实例对象的静态方法
Promise.resolve
它可以认为是
new Promise(function(resolve, reject) { resolve();})
Promise.resolve的返回值是一个Promise对象,所以继续可以用then调用,所以Promise.resolve也可以认为是new Promise的快捷形式
Promise.resolve的另外一个作用就是将thenable对象转换为promise对象,thenable对象就是指的是一个具有.then方法的对象,这种将thenable对象转换为promise对象的机制要求thenable对象所拥有的then方法应该和Promise所拥有的then方法具有相同的功能和处理过程,再将thenabel对象转换为promise对象的时候,还会巧妙的利用thenable对象原来所具有的then方法
thenable
最简单的例子就是jQuery.ajax(),它的返回值就是thenable的,将thenable转换为Promise对象的时候,就可以调用then和catch方法
/*将thenable对象转换为Promise对象*/var promise = Promise.resolve($.ajax('https://httpbin.org/get'));promise.then(function(value) { console.log(value); //jQuery ajax的返回值是一个具有.then方法的jq XHR Object对象,这个对象继承了来自Deferred Object的方法和属性});
var ary = [1, 2, 3, 4, 5];for(var i = 0; i < ary.length; i++) { Promise.resolve(ary[i]).then(function(d) { console.log(d); });}
输出结果为:
1 2 3 4 5
Promise.reject
它相当于
new Promise(function(resolve, reject) { reject(new Error("出错了"));});
备注
Promise保证了每次的调用都是以异步的方式进行的,所以在实际代码中不需要调用setTimeout来自己实现异步
function test() { console.log("test-1"); return new Promise(function(resolve, reject) { console.log("test-2"); resolve("test-test"); }); } test().then(function(data) { console.log(data); }, function() { console.log("error"); }); console.log("test-outer");
结果:
test-1
test-2
test-outer
test-test
处理多个异步请求
Peomise方法链
promise.then(function taskA(value) { //task A }).then(function taskB(value) { //task B }).then(function taskC(value) { //task C }).catch(function onRejected(error) { console.log(error); });
在每一个task的方法中,都可以包含一个return
语句,返回的值也可以是一个Promise对象,return
的值会Promise.resolve(return的返回值);进行相应的包装处理,因此不管回掉函数中返回一个怎样的值最终then
的结果都是返回一个新创建的promise对象
catch
调用catch的时候,只是promise.then(undefined, onRejected)方法的一个别名而已,这个方法用来注册当promise对象状态变为Rejected时的回掉函数
then和catch的处理错误的区别:
- .then和catch都会创建并返回一个新的Promise对象。Promise实际上每次在方法链上增加一次处理的时候所操作的都不是完全相同的promise对象
- .then(resolve, reject)其中这个reject并不能捕获resolve中的错误,而.catch(reject)总会捕获它前面出现的错误
- 使用.then(null, reject)可以完成.catch同样的工作,只不过使用.catch的意图更加明确,易于理解
总结:
1. 使用 promise.then(onFulfilled, onRejected) 的话
• 在 onFulfilled 中发生异常的话,在 onRejected 中是捕获不到这个异常的。
2. 在 promise.then(onFulfilled).catch(onRejected) 的情况下
• then 中产生的异常能在 .catch 中捕获
3. .then 和 .catch 在本质上是没有区别的
• 需要分场合使用。
Promise.all
Promise.all
接收一个Promise对象的数组作为参数,当这个数组的所有Promise对象全部变为resolve或reject的时候,它才回去调用.then方法
function getURL(URL) { return new Promise(function(resolve, reject) { var req = new XMLHttpRequest(); req.open("Get", URL, true); req.onload = function() { if (req.status === 200) { resolve(req.responseText); }else { reject(new Error(req.statusText)); } }; req.onerror = function() { reject(new Error(req.statusText)); }; req.send(); });}var request = { comment : function getComment() { return getURL('https://azu.github.io/promises-book/json/comment.json').then(JSON.parse); }, people: function getPeople() { return getURL('https://azu.github.io/promises-book/json/people.json').then(JSON.parse); }};function main() { return Promise.all([request.comment(), request.people()]);}main().then(function(value) { console.log(value);}).catch(function(error) { console.log(error);});
Promise.all([request.comment(), request.people()])
会同时开始执行,而且每个promise
的结果(resolve或者reject时传递的参数值),和传递给Promise.all
的promise
数组的顺序是一致的,也就说这里面的then
中的value的值,也是是得到的两个JSON对象也是按照[comment,people]的进行排列的
所以传递给Promise.all
的Promise
不是一个个顺序执行的,而是同时开始的并行完成的
Promise.race
Promise.race
使用的方法和Promise.all
一样对多个Promise对象
进行并行处理,但是Promise.all在接收到所有的对象的状态都变成FullFilled
或者Reject
状态之后才会进行相应的处理,与之相对的是Promise.race
只要有一个promise对象进入FulFilled状态或者Rejected状态的话,就会进行后面的处理
function tst1() { return new Promise(function(resolve, rejecct) { resolve(20); });}function tst2() { return new Promise(function(resolve, rejecct) { resolve(88); })};Promise.race([tst1(), tst2()]).then(function(data) { console.log(data);});
输出的结果:
20
function timerPromisefy(delay) { return new Promise(function(resolve) { setTimeout(function() { resolve(delay); }, delay); });}Promise.race([timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128)]).then(function(data) { console.log(data); });
输出的结果:
1
换成下面的这样:
Promise.all([timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128)]).then(function(data) { console.log(data); });
输出的结果:
[1, 32, 64, 128]
补充
事件的注册顺序如下:
setImmediate - setTimeout - promise.then - process.nextTick
因此,我们得到了优先级关系如下:
process.nextTick > promise.then > setTimeout > setImmediate
setTimeout(function(){console.log(4)},0);new Promise(function(resolve){ console.log(1) for( var i=0 ; i<10000 ; i++ ){ i==9999 && resolve() } console.log(2)}).then(function(){ console.log(5)});console.log(3);
输出结果:
1 2 3 5 4
参考:javascript-promise-book
- 关于Promise的总结
- 百度一道关于promise笔试题的总结
- 关于std::promise的set_value_at_thread_exit
- 关于Promise.then()的思考
- Promise 总结
- 关于promise 的测试用例编写
- 一道关于Promise应用的面试题
- 关于一道promise的面试题
- 关于Promise与async/await的例子
- 关于axios和promise的理解
- 关于 new Promise 和 Promise.resolve()
- Promise特性总结
- promise 特点总结
- 关于ES6的Promise的使用深入理解
- ionic2页面回传值,关于Typescript的Promise承诺
- Javascript关于promise的学习和运行时机
- 关于Promise,Generator,async / await 对异步的处理
- 关于Promise:你可能不知道的6件事
- 2017.7.16C++输入输出
- 基于Token的WEB后台认证机制
- 虚幻4shader 初步研究
- 1070. 结绳(25)
- 【C程序】逻辑判断真假话问题:3人说真话,1人说假话
- 关于Promise的总结
- C++ -> 向量(vector)
- Leetcode#169. Majority Element(四种解法)
- Vuex速学篇:(1)基本套路
- [APIO2009]抢掠计划
- Java判断单链表是否有环的两种实现方法
- Maven详解
- Unity3D架构之PureMVC
- JavaSE_笔试题_简答题1