# Promise
最简实现 Promise,支持异步链式调用(20 行 (opens new window)
# 基础术语
promise 是一个包含 then 方法的对象或函数,该方法符合规范指定的行为
thenable 是一个包含 then 方法和对象或者函数
value 就是任意合法 JS 值
exception 就是 throw 语句抛出的值
reason 是一个指示 promise 为什么被 rejected 的值
const isFunction = (obj) => typeof obj === 'function'
const isObject = (obj) => !!(obj && typeof obj === 'object')
const isThenable = (obj) => (isFunction(obj) || isObject(obj)) && 'then' in obj
const isPromise = (promise) => promise instanceof Promise
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(f) {
this.result = null
this.state = PENDING
this.callbacks = []
let onFulfilled = (value) => transition(this, FULFILLED, value)
let onRejected = (reason) => transition(this, REJECTED, reason)
let ignore = false
let resolve = (value) => {
if (ignore) return
ignore = true
resolvePromise(this, value, onFulfilled, onRejected)
}
let reject = (reason) => {
if (ignore) return
ignore = true
onRejected(reason)
}
try {
f(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
let callback = { onFulfilled, onRejected, resolve, reject }
if (this.state === PENDING) {
this.callbacks.push(callback)
} else {
setTimeout(() => handleCallback(callback, this.state, this.result), 0)
}
})
}
const handleCallback = (callback, state, result) => {
let { onFulfilled, onRejected, resolve, reject } = callback
try {
if (state === FULFILLED) {
isFunction(onFulfilled) ? resolve(onFulfilled(result)) : resolve(result)
} else if (state === REJECTED) {
isFunction(onRejected) ? resolve(onRejected(result)) : reject(result)
}
} catch (error) {
reject(error)
}
}
const handleCallbacks = (callbacks, state, result) => {
while (callbacks.length) handleCallback(callbacks.shift(), state, result)
}
const transition = (promise, state, result) => {
if (promise.state !== PENDING) return
promise.state = state
promise.result = result
setTimeout(() => handleCallbacks(promise.callbacks, state, result), 0)
}
const resolvePromise = (promise, result, resolve, reject) => {
if (result === promise) {
let reason = new TypeError('Can not fufill promise with itself')
return reject(reason)
}
if (isPromise(result)) {
return result.then(resolve, reject)
}
if (isThenable(result)) {
try {
let then = result.then
if (isFunction(then)) {
return new Promise(then.bind(result)).then(resolve, reject)
}
} catch (error) {
return reject(error)
}
}
resolve(result)
}
module.exports = Promise
# async
async 表示函数里有异步操作
返回值是 Promise
async 函数的语法规则总体上比较简单,难点是错误处理机制
# await
- 正常情况下,await 命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值