博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单理解promise
阅读量:5923 次
发布时间:2019-06-19

本文共 4223 字,大约阅读时间需要 14 分钟。

含义

异步编程的一种解决方案。是一个构造对象,代表一个异步操作。有3种状态:

pending(进行中)、fulfilled(已成功)、rejected(已失败)。

状态变更: pending -> fulfilled、pending -> rejected。

状态变更后就永久保持这个结果。

基本用法

const p = new Promise((resolved, rejected) => {    if(/*异步操作成功*/) {        resolved(value);    }else{        rejected(error);    }});p.then((value) => console.log('异步执行成功:' + value),  //异步调用回调写法1    (error) => console.log('异步执行失败:' + error))p.then((value) => console.log('异步执行成功:' + value))  //异步调用回调写法2    .catch((error) => console.log('异步执行失败:' + error))复制代码

pending -> fulfilled执行的结果是resolved,

pending -> rejected执行的结果是rejected。

用法

then() catch()

基本用法中的写法1和写法2的效果一样,主要是因为promise.prototype.then() 有两个参数,第一个参数是 resolved 的回调,第二个参数(可选)是 rejected 的回调。

而promise.prototype.catch()主要用来捕获异步操作抛出的错误,与try{}catch(){}中的catch功能一样。promise.prototype.catch()除了能够捕获异步操作中的错误外,还能捕获.then()回调中的错误。

const p = new Promise((resolved, rejected)=>resolved('resolved')).then((value) => {    throw new Error(value);}, (error) => {}).catch((error) => console.log(error))复制代码

输出结果为

另外,当Promise状态已变成resolved之后再抛出错误,抛出的错误是无效的,同样以上面的例子为例。

const p = new Promise((resolved, rejected) => {    resolved('resolved');    throw new Error('hhh');}).then((value) => {    throw new Error(value);}, (error) => {}).catch((error) =>console.log(error))复制代码

输出结果

与上面的结果一致。原因: Promise的状态变更后就永久保持这个结果,不会再变化了。 .catch()返回的仍是一个Promise对象,在执行.catch之后,仍可以继续调用。

const p = new Promise((resolved, rejected) => {    resolved('hhh');}).then((value) => {     throw new Error(value);}).catch((error) =>console.log(error)).then(() => console.log('hhhhh'))复制代码

输出结果:

错误捕获

.catch()具有冒泡的性质,会一直向后传递,直到被捕获为止,也就是说错误总会被下一个catch捕获。.catch()也能捕获前一个.catch()抛出的错误。

const p = new Promise((resolved, rejected) => {    resolved('hhh');}).then((value) => {     throw new Error(value);}).catch((error) =>{    console.log(r)})    throw new Error('hhhh').catch((error) => console.log(error))复制代码

输出结果:

注意:一般不要使用.then()的第二个参数

举例:

p.then((value) => { //写法1    throw new Error(value);}).catch((error) =>console.log(error))p.then((value) => { //写法2    throw new Error(value);}, (error) => console.log(error))复制代码

写法1能够捕获前面then()中抛出的错误,但写法2不行

由于.catch()的冒泡性质,当一个promise函数体未对错误进行捕获并进行处理,运行后不会有任何输出,但是浏览器会打印报错。

Node有一个事件unhandledRejection,专门用来监听未捕获的reject错误。

process.on('unhandledRejection', (err, p) => {})复制代码

unhandledRejection有两个参数:

err:错误对象

p:报错的Promise实例

Promise.all([])

Prmise.all()用于将多个Promise实例包装成一个新的promise实例。

语法: var p = Promise.all([p1,p2,p3])

p1,p2,p3必须都是Promise实例。若其参数不是Promise实例,则会通过将其转为Promise实例再传给Promise.all()

p的状态由p1,p2,p3决定:

1、p1,p2,p3状态都变为Fulfilled,p的状态才变为Fulfilled。

2、p1,p2,p3中有任一个状态变为Rejected,p的状态就变为Rejected。

注意:若作为参数的Promise实例自身定义了catch,则它被rejected并不会触发Promise.all()的catch()。

const p1 = new Promise((resolved) => {    resolved('hhh');}).then((value) => value).catch((error) => error);const p2 = new Promise(() => {    throw new Error('hhhhh');}).then((value) => value).catch((error) => error);Promise.all([p1, p2]).then((result) => console.log(result)).catch((error) => console.log(error));复制代码

输出:走到了Promise的then(),正常输出

Promise.race()

跟上面的Promise.all()一样,都是将多个Promise实例包装成一个新的Promise实例

语法: var p = Promise.race([p1,p2,p3])

p的状态由p1,p2,p3中最先改变状态的实例决定。

Promise.resolve()

作用: 将先有的对象转为Promise对象。

let foo = () => console.log('foo')Promise.resolve(foo)复制代码

等价于

new Promise((resolve) => resolve(foo));复制代码

参数:

1、Promise实例:不做任何修改,直接返回该实例

2、带有then()的对象:将这个对象转为Promise对象并立即执行then方法。

let foo ={    then : (resolve) => resolve('foo')}let p1 = Promise.resolve(foo)p1.then((value) => console.log(value))复制代码

这里会输出'foo',因为p1会立即执行foo的then方法,执行后p1的状态才变为resolved。

这个用法比较常用,当异步调用多个接口改变数据,但后面需要同时处理改变后的这些数据时,可结合Promise.all和Promise.resolve()来使用。

3、参数不是对象

Promise.resolve('foo');

该用法在Promise实例生成时状态就为Resolved,所有回调函数会立即执行,并将参数传给Promise的回调函数。

4、不带参数:返回一个空Promise实例

注意:Promise.resolve()是在本轮"事件循环"结束时执行

因为setTimeout是在下轮“事件循环”开始时执行,console.log(3)立即执行,因此有了这样的输出结果。

Promise.reject()

返回一个新的Promise实例,状态为rejected。

该方法的参数会被原封不动的传给Promise.catch()作为参数。不区分该参数类型。

.done()

处于回调链的低端,保证能够接收抛出的任何可能的错误。

.finally()

用于指定不管Promise对象最后状态如何都会执行的操作。它接收的回调函数作为参数。

比如:调用接口时会对接口做处理,不论接口调用成功还是失败,都要做出提示,那么就可以用这个方法用来做提示的回调。

.try()

实际中会遇到不知道或者不想区分回调函数是同步的还是异步的,但是想用Promise

处理,因为这样就可以不管回调函数是同步还是异步,都能使用then()指定下一步操作,用catch捕获错误。

Promise.try()的作用就是解决上面的问题。

以上,属于个人学习promise之后对promise的简单理解。

转载地址:http://trivx.baihongyu.com/

你可能感兴趣的文章
转一篇Linux可用内存的统计方法
查看>>
oracle的一些孤僻性错误(OCIEnvCreate failed)
查看>>
settings.xml配置的镜像
查看>>
isted系列教程三–开始twisted
查看>>
《软件需求十步走》阅读笔记4
查看>>
OUTLOOK之不能直接发送邮件的Mapi错误解决方法
查看>>
( 转 ) Android自绘字体大小paint.settextsize随分辨率大小变化
查看>>
关于MySql链接url参数的设置 专题
查看>>
Python 目录操作(转)
查看>>
java 二维码原理以及用java实现的二维码的生成、解码(转)
查看>>
log4net小结
查看>>
支线任务-4
查看>>
【PHP】最详细PHP从入门到精通(一)——想学习PHP的朋友们福利来了!
查看>>
[android] 帧布局
查看>>
iis6 zencart1.39 伪静态规则
查看>>
java使用jxl,poi解析excel文件
查看>>
vue的入门
查看>>
看看C# 6.0中那些语法糖都干了些什么(终结篇)
查看>>
结构体与字符串之间的转换
查看>>
隐藏桌面图标和任务栏
查看>>