Promise 的三种状态
- Pending 进行中
- Fulfilled 已成功
- Rejected 已失败
状态转变
Promise对象的状态,只有两种情况:
- Pending 变为 Fulfilled
- Pending 变为 Rejected
基本用法
// 返回一个 promise 对象
const createPromise = () => {
return new Promise((resolve, reject) => {
// some code...
if (false) {
resolve()
} else {
reject()
}
})
}
// promise 对象内部执行 resolve() 时,会执行该函数
// resolve() 的参数传给该函数
const onFulfilled = () => {
console.log('成功')
}
// promise 对象内部执行 reject() 时,会执行该函数
// reject() 的参数传给该函数
const onRejected = () => {
console.log('失败')
}
let promiseObj = createPromise()
// <= 关键: 设置resolve()和reject() 时执行的函数
promiseObj.then(onFulfilled, onRejected)
let promiseObj = createPromise()
// 也可以使用 .catch() 方法代替 .then(null, onRejected)
promiseObj
.then(onFulfilled)
.catch(onRejected)
简单的例子
// 间隔一段时间后执行
const timeout = (ms, str) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, str) // str 作为 resolve函数的参数
})
}
let timeOutPromise = timeout(1000, 'hello promise')
timeOutPromise.then((str) => {
console.log('then:' + str)
})
// 100ms后输出
// then:hello promise
Promise 新建后立即执行
// Promise 对象创建后立即执行
let promiseObj = new Promise((resolve, reject) => {
console.log('inner log') // <= 1
resolve()
})
promiseObj.then(()=>{
console.log('then log') // <=3
})
console.log('outer log') // <=2
一个异步操作的结果是返回另一个异步操作
let p1 = new Promise((resolve, reject) => {
setTimeout(()=>reject(new Error('p1 fail')), 3000) // 3 秒后执行
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(p1), 1000) // <= resolve的参数为另一个 promise对象且处于Pending状态
})
p2
.then(result => console.log(result))
.catch(error => console.log(error.toString()))
// 3秒后输出
// Error: p1 fail
上面的例子中,p2 的 resolve() 方法把 p1 作为参数,此时 p1 的状态就会传递给 p2。
也就是说,p1 的状态决定了 p2 的状态。如果 p1 的状态是 Pending,那么 p2的回调函数就会等待 p1 的状态改变,如果 p1 的状态已经是 Resolved 或 Rejected,那么 p2 的回调函数将会立刻执行。
let p1 = new Promise((resolve, reject) => {
setTimeout(()=>reject(new Error('p1 fail')), 1000) // 1 秒后执行
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(p1), 2000) // 2 秒后执行,执行时 p1 处于 Rejected 状态
})
p2
.then(result => console.log('p2 then', result))
.catch(error => console.log('catch', error.toString()))
// 输出
(node:9620) UnhandledPromiseRejectionWarning: Error: p1 fail
at Timeout.setTimeout [as _onTimeout] (E:\AllCode\Code\html+css+js\23_promise小书\src\06.pro
mise.js:2:25) <= 第2行的reject(),没有处理 onRejected 函数
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at listOnTimeout (timers.js:263:5)
at Timer.processTimers (timers.js:223:10)
(node:9620) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated
either by throwing inside of an async function without a catch block, or by rejecting a promise
which was not handled with .catch(). (rejection id: 1)
(node:9620) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the fu
ture, promise rejections that are not handled will terminate the Node.js process with a non-zero
exit code.
catch Error: p1 fail <= 执行 catch 语句
(node:9620) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (reject
ion id: 1)
let p1 = new Promise((resolve, reject) => {
setTimeout(()=>resolve(new Error('p1 fail')), 1000) // 1 秒后执行,p1 状态为 Resolved
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(p1), 2000) // 此时 p1 的状态为 Resolved,立即执行 .then 回调
})
p2
.then(result => console.log('p2 then', result.toString())) // result 为 p1的resolve参数, error 对象
.catch(error => console.log('catch', error.toString()))