JS学习-Promise
Promise
一个 Promise 必然处于以下几种状态之一:
- 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled): 意味着操作成功完成。
- 已拒绝(rejected): 意味着操作失败。
如果一个 promise 已经"被兑现(fulfilled)"或"被拒绝(rejected)",那么我们也可以说它处于"已敲定(settled)"状态。
您还会听到一个经常跟 promise 一起使用的术语:"已决议(resolved)",任何不是 throw 的终止都会创建一个"已决议(resolved)"状态,而以 throw 终止则会创建一个"已拒绝(rejected)"状态。
链式调用
const myPromise = (new Promise(myExecutorFunc))
.then(handleFulfilledA)
.then(handleFulfilledB)
.catch(handleRejectedAny)
.finally(handleFinalAny);
自定义Promise
const promiseA = new Promise( (resolve,reject) =>{resolve(777);});
// 这时,"promiseA" 已经被敲定了。
promiseA.then( (val) => console.log("asynchronous logging has val:",val) );
构造函数
new Promise((resolve,reject)=>{})
function fetchUserList(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", '/user/list')
xhr.onload = () => resolve(xhr.responseText)
xhr.onerror = () => reject(xhr.statusText)
xhr.send()
});
}
静态方法
all
- 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的Promise。
- 如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved) Promise。
- 其它情况下返回一个处理中(pending)的Promise。
//注:Array,Map,Set都属于ES6的iterable类型
Promise.all(iterable);
const p1 = Promise.resolve(3),p2 = Promise.reject(4),p4 = 42,p5="42";
const p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p4, p3]).then((values) => {
console.log(values);
});
Promise.all([p4, p5]).then((values) => {
console.log(values);
});
p2.then(v=>{console.log(v);}).catch(e=>{
console.log('error:',e);
});
/*
> Array [42, "42"]
> "error:" 4
> Array [3, "foo", "foo"]
*/
allsettled:返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
Promise.allSettled(iterable);
const p1 = Promise.resolve(1),p2 = Promise.reject(2);
Promise.allSettled([p1,p2]).then((res) => console.log(res));
//Array[Object{status: "fulfilled",value: 1},Object{status:"rejected",reason:2}]
any:接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。
Promise.any(iterable);
const p1 = Promise.resolve(1),p2 = Promise.reject(2);
Promise.any([p2,p1])
.then((res) => console.log(res))
.catch((e)=>console.log('error;',e));//1
race:返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
Promise.race(iterable);
const p1 = Promise.resolve(1),p2 = Promise.reject(2);
Promise.race([p2,p1])
.then((res) => console.log(res))
.catch((e)=>console.log('error;',e));//"error;" 2
reject:返回一个带有拒绝原因的Promise对象。
Promise.reject(reason);
resolve:返回一个以给定值解析后的Promise 对象。
Promise.resolve(value);
原型
方法
- then(onFufilled,onRejected):返回一个 Promise
- catch(onRejected):返回一个Promise (en-US),并且处理拒绝的情况。
- finally(onFinally):返回一个Promise。在promise结束时调用。
- 由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。
注意: 在finally回调中 throw(或返回被拒绝的promise)将以 throw() 指定的原因拒绝新的promise.
事件处理函数
rejectionhandled:当Promise被rejected且有rejection处理器时会在全局触发rejectionhandled 事件(通常是发生在window下,但是也可能发生在Worker中)。应用于调试一般应用回退。
window.addEventListener("rejectionhandled", event => {
console.log("Promise rejected; reason: " + event.reason);
}, false);
unhandledrejection:当Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;这可能发生在 window 下,但也可能发生在 Worker 中。
//onunhandledrejection(event:{promise,reason})
window.addEventListener("unhandledrejection", event => {
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
}); window.onunhandledrejection = event => {
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
// 防止默认处理(例如将错误输出到控制台)
event.preventDefault();
};
Promise 与 async/await
function foo() {
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log(`Got the final result: ${finalResult}`))
.catch(failureCallback);
}
async function foo() {
try {
const result = await doSomething();
const newResult = await doSomethingElse(result);
const finalResult = await doThirdThing(newResult);
console.log(`Got the final result: ${finalResult}`);
} catch(error) {
failureCallback(error);
}
}
旧式回调API
- setTimeout
setTimeout(() => saySomething("10 seconds passed"), 10000);
问题:如果 saySomething 函数失败了,或者包含了编程错误,那就没有办法捕获它了。这得怪 setTimeout。
解决方法:可以用 Promise 来封装它。最好的做法是,将这些有问题的函数封装起来,留在底层,并且永远不要再直接调用它们 解决方法:可以用 Promise 来封装它。最好的做法是,将这些有问题的函数封装起来,留在底层,并且永远不要再直接调用它们
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
wait(10000)
.then(() => saySomething("10 seconds")).catch(failureCallback);
组合Promise
多个并行
Promise.all([func1(), func2(), func3()])
.then(([result1, result2, result3]) => {
/* use result1, result2 and result3 */
});
reduce时序
[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
.then(result3 => { /* use result3 */ });
Promise链
Promise.resolve().then(func1).then(func2).then(func3);
函数式reduce时序
const applyAsync = (acc,val) => acc.then(val);
const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));
async/await时序
let result;
for (const f of [func1, func2, func3]) {
result = await f(result);
}
示例:() => x
是 () => { return x; }
的简写。
doSomething()
.then(function(result) {return doSomethingElse(result);})
.then(newResult => doThirdThing(newResult))
.catch(error => console.log(error));
JS学习-Promise的更多相关文章
- 关于学习js的Promise的心得体会
最近一直在研究js的Promise对象,其中有一篇blog写得比较通俗易懂,转发如下: http://www.cnblogs.com/lvdabao/p/es6-promise-1.html 参照上面 ...
- 学习Promise笔记
什么是Promise? MDN对Promise的定义:Promise对象用于异步操作,它表示一个尚未完成且预计在未来完成的异步操作. 在学习Promise之前得先了解同步与异步:JavaScript的 ...
- js的promise
转载自: https://segmentfault.com/a/1190000007032448#articleHeader16 一 前言 本文主要对ES6的Promise进行一些入门级的介绍.要想学 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- js学习之变量、作用域和内存问题
js学习之变量.作用域和内存问题 标签(空格分隔): javascript 变量 1.基本类型和引用类型: 基本类型值:Undefined, Null, Boolean, Number, String ...
- 【Knockout.js 学习体验之旅】(3)模板绑定
本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(2)花式捆绑
本文是[Knockout.js 学习体验之旅]系列文章的第2篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
- js学习篇1--数组
javascript的数组可以包含各种类型的数据. 1. 数组的长度 ,直接用 length 属性; var arr=[1,2,3]; arr.length; js中,直接给数组的length赋值是会 ...
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
随机推荐
- 【27期】Dubbo面试八连问,这些你都能答上来吗?
1.Dubbo是什么? Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目.致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA ...
- 关于java业务限流组件的应用推广
可参考的链接如下: 限流算法对比.网关限流实践总结(https://segmentfault.com/a/1190000020745218) 高并发下常见的限流算法(https://www.jians ...
- pip安装psycopg2报错Could not find a version that satisfies the requirement psycopg2
pip安装psycopg2报错 在使用命令(pip install psycopg2)安装psycopg2时,会报错: ERROR: Could not find a version that sat ...
- Rstudio 快捷键无法使用
今天突然发现我的R studio 很多快捷键不能使用,后面发现是因为Rstudio 的快捷键与MobaXterm的快捷键起冲突了,后面关掉MobaXterm后就恢复了,如果有类似的问题可以在自己电脑打 ...
- Github好用的镜像网站
最近Github越来越不好用了,发现一个特别好用的镜像网站,无论是进入还是下载都非常的快. https://hub.yzuu.cf/ 首页和Github没有任何区别, 注意请不要在连着梯子的时候使用, ...
- iOS 绘制虚线
开发中经常用到虚线 创建一个imageView,直接调用下面的代码就可以了!,imageView的高一般设置2像素就可以了 - (void)drawLineByImageView:(UIImageVi ...
- 超级详细的Vue安装与配置教程
原文: https://www.jb51.net/article/251371.htm 超级详细的Vue安装与配置教程 Vue web前端三大主流框架之一,是一套用于构建用户界面的渐进式框架,下面 ...
- 靶机练习6: BSS(Cute 1.0.2)
靶机地址 https://www.vulnhub.com/entry/bbs-cute-102,567/ 信息收集 进行全端口扫描,确认目标开放端口和服务 nmap -n -v -sS --max-r ...
- 用xmind转换成excel表格
我的版本是: XMind 8 Update 9 (R3.7.9.201912052356) 1.先下载一个xmind软件,并注册账号,建议最好用qq邮箱去注册 2.然后下载一个 XMindCrack. ...
- web执行shell脚本
转载请注明来源:https://www.cnblogs.com/Sherlock-L/p/15584456.html 缘起 去年写过一个shell脚本用来校验统计打点,工作使用.发现同事不太熟悉这块, ...