Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。 promise
有三种状态:pending
( 等待态 ),fulfiled
( 成功态 ),rejected
( 失败态 ) 状态一旦改变,就不会再变。创造promise
实例后,它会立即执行。
promise是用来解决两个问题的:
- 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
promise
可以支持多个并发的请求,获取并发请求中的数据promise
可以解决异步的问题,本身不能说promise
是异步的
Promise.prototype.then()和Promise.prototype.catch()
resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。
一般来说,不要在
then()
方法里面定义 Reject 状态的回调函数(即then
的第二个参数),总是使用catch
方法。
1 | // 不建议这么使用 |
第二种写法可以捕获前面then
方法执行中的错误,也更接近同步的写法(try/catch
)。
Promise.prototype.finally()
finally()
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
1 | promise.then(result => { |
上面代码中,不管
promise
最后的状态,在执行完then
或catch
指定的回调函数以后,都会执行finally
方法指定的回调函数。finally
方法的回调函数不接受任何参数,应该是与状态无关的,不依赖于 Promise 的执行结果。finally
方法总是会返回原来的值。
Promise.all()
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
1 | const p = Promise.all([p1, p2, p3]); |
Promise.all()
方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
Promise.race()
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
1 | const p = Promise.race([p1, p2, p3]); |
Promise.race()
方法的参数与Promise.all()
方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve()
方法,将参数转为 Promise 实例,再进一步处理。
Promise.allSettled()
Promise.allSettled()
方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled
还是rejected
,包装实例才会结束。该方法由 ES2020 引入。
1 | const promises = [ |
Promise.allSettled()
的返回值allSettledPromise
,状态只可能变成fulfilled
。它的监听函数接收到的参数是数组results
。该数组的每个成员都是一个对象,对应传入Promise.allSettled()
的两个 Promise 实例。每个对象都有status
属性,该属性的值只可能是字符串fulfilled
或字符串rejected
。fulfilled
时,对象有value
属性,rejected
时有reason
属性,对应两种状态的返回值。
1 | const resolved = Promise.resolve(42); |
有时候,我们不关心异步操作的结果,只关心这些操作有没有结束。这时,Promise.allSettled()
方法就很有用。如果没有这个方法,想要确保所有操作都结束,就很麻烦。Promise.all()
方法无法做到这一点。
1 | const urls = [ /* ... */ ]; |
Promise.any()
ES2021 引入了Promise.any()
方法。该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。只要参数实例有一个变成fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。