Promise
创建 Promise (执行器函数的同步执行):
- 当你使用
new Promise((resolve, reject) => { ... })
创建一个 Promise 实例时,传递给构造函数的执行器函数 (executor function) 会被立即同步执行。 - 这个执行器函数接收两个参数:
resolve
和reject
。这两个参数本身也是函数,由 JavaScript 引擎提供,用于改变 Promise 的状态。 - 在执行器函数内部,你通常会启动一个异步操作(比如网络请求
Workspace
、定时器setTimeout
、文件读写等)。
- 当你使用
resolve
,reject
会使Promise的状态发生改变- 如果操作成功,执行器函数内部应该调用
resolve(value)
。这会将 Promise 的状态从pending
变为 fulfilled (已兑现),并且value
会作为 Promise 的结果值。 - 如果操作失败,执行器函数内部应该调用
reject(reason)
。这会将 Promise 的状态从pending
变为 rejected (已拒绝),并且reason
(通常是一个 Error 对象) 会作为 Promise 的拒绝原因。
- 如果操作成功,执行器函数内部应该调用
然后可以注册回调函数 (
.then()
,.catch()
,.finally()
)- 这三个方法都可以接收函数参数执行注册回调函数
这些方法可以在 Promise 落定之前或之后调用
- 如果调用时 Promise 还是
pending
,回调函数会被存储起来,等待 Promise 落定后再执行。 - 如果调用时 Promise 已经
fulfilled
或rejected
,相应的回调函数会被调度为异步执行(通常是放入微任务队列)。
- 如果调用时 Promise 还是
回调函数的异步执行 (微任务队列 Microtask Queue)
- 即使 Promise 的
resolve
或reject
立即执行了,通过.then()
,.catch()
, 或.finally()
注册的回调函数也不会立即同步执行。这些回调会被放入微任务队列 (Microtask Queue) 中。 - 在当前同步代码块执行完毕后,会检查微任务队列。如果队列中有任务,会依次取出并执行,直到微任务队列清空。然后才会去处理宏任务队列 (Macrotask Queue,如
setTimeout
的回调、I/O 事件等)
- 即使 Promise 的
async/await
- 带
async
的函数返回Promise
,这类函数里可以使用await
关键字。 await
关键字用于等待一个 Promise 落定。它会暂停async
函数的执行,直到await
后面的 Promisefulfilled
(然后返回其结果值) 或rejected
(然后抛出其拒绝原因,可以被try...catch
捕获)。async
可以主动返回Promise
,但是这个Promise
前带不带await
有点区别:- 如果是直接
return new Promise()
那么这个Promise
会被直接返回 - 如果
return await new Promise()
这个await
会等待后面的Promise
落定
- 如果是直接
async
不主动返回Promise
:async function foo() { return 'Hello, World!'; }
这里返回的值会自动成为一个已解决的
Promise
的值。foo().then(message => console.log(message)); // 输出 'Hello, World!'
例题
leetcode 2621. 睡眠函数
https://leetcode.cn/problems/sleep/description/
async function sleep(millis) {
return new Promise(resovle => {
setTimeout(resovle, millis)
})
}
/**
* let t = Date.now()
* sleep(100).then(() => console.log(Date.now() - t)) // 100
*/
在调用sleep(100).then(() => console.log(Date.now() - t))
时,执行器函数执行异步函数setTimeout(resovle, millis)
,在等待millis
秒后,resovle
执行,返回的或者Promise
状态改变,此时使用.then
方法注册回到函数() => console.log(Date.now() - t)
立即执行