ES5中的Generator异步方案
Generator使用
function* foo() {
console.log('start')
try {
const res = yield 'foo'
console.log(res) // bar
} catch (e) {
console.log(e)
}
}
const generator = foo()
const res = generator.next()
console.log(res) // Object { value: "foo", done: false }
generator.next('bar')
// generator.throw(new Error('error'))
Gernerator配合Promise的异步方案
function* main() {
const users = yield fetch('https://jsonplaceholder.typicode.com/users')
console.log('users', users)
const posts = yield fetch('https://jsonplaceholder.typicode.com/posts')
console.log('posts', posts)
}
const g = main()
const res = g.next()
res.value.then(data => {
const res2 = g.next(data) // data: users
if (res2.done) return
res2.value.then(data => {
const res3 = g.next(data) // data: posts
})
})
function* main() {
try {
const users = yield fetch('https://jsonplaceholder.typicode.com/users')
console.log('users', users)
const posts = yield fetch('https://jsonplaceholder.typicode.com/posts')
console.log('posts', posts)
const e = yield fetch('https://helloworld')
console.log('e', e)
} catch (e) {
console.log('error', e)
}
}
const co = generator => {
const g = generator()
const handleResult = result => {
if (result.done) return
result.value.then(
data => {
handleResult(g.next(data))
},
error => g.throw(error)
)
}
handleResult(g.next())
}
co(main)
ES6中的async, await语法糖
async function main() {
try {
const users = await fetch('https://jsonplaceholder.typicode.com/users')
console.log('users', users)
const posts = await fetch('https://jsonplaceholder.typicode.com/posts')
console.log('posts', posts)
} catch (e) {
console.log('error', e)
}
}
const promise = main()
promise.then(() => {
console.log('all done')
})
手写Promise
核心逻辑实现
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
const resolvePromise = (promise, x, resolve, reject) => {
if (promise === x) {
// 防止自己返回自己
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
status = PENDING
value = undefined
reason = undefined
successCallback = []
failCallback = []
resolve = value => {
if (this.status !== PENDING) return // 状态一旦改变就不能再更改
this.status = FULFILLED
this.value = value
// 判断成功回调是否存在,存在就调用
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// 判断失败回调是否存在,存在就调用
while (this.failCallback.length) this.failCallback.shift()()
}
then = (successCallback, failCallback) => {
successCallback = successCallback ? successCallback : value => value
failCallback = failCallback
? failCallback
: reason => {
throw reason
}
let promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
// 成功
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise, x, resolve, reject) // 实现then方法的链式调用
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
// 失败
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise, x, resolve, reject) // 实现then方法的链式调用
} catch (e) {
reject(e)
}
}, 0)
} else {
// 异步等待
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value)
resolvePromise(promise, x, resolve, reject) // 实现then方法的链式调用
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason)
resolvePromise(promise, x, resolve, reject) // 实现then方法的链式调用
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise
}
}
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功')
}, 2000)
// resolve('成功')
// reject('失败')
})
promise
.then()
.then()
.then(value => {
console.log(value)
return 'aaa'
})
.then(value => {
console.log(value)
})
Promise.all的实现
static all = array => {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i]
if (current instanceof MyPromise) {
// promise 对象
current.then(
value => addData(i, value),
reason => reject(reason)
)
} else {
// 普通值
addData(i, array[i])
}
}
})
}
Promise.resolve的实现
static resolve = value => {
if (value instanceof MyPromise) return value
return new MyPromise(resolve => resolve(value))
}
.finally、.catch方法的实现
finally = callback => {
return this.then(
value => {
return MyPromise.resolve(callback()).then(() => value)
},
reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason
})
}
)
}
catch = failCallback => {
return this.then(undefined, failCallback)
}