async/await 出现的原因是什么?
Promise
的编程模型依然充斥着大量的then
方法,虽然解决了回调地狱的问题,但是在语义方面依然存在缺陷,代码中充斥着大量的then
函数。
使用async/await的好处是什么?怎么实现的?
使用async/await
可以实现用同步代码的风格来编写异步代码,不仅能让代码更加整洁美观,而且还能确保该函数始终都返回Promise
。这是因为async/await
的基础技术使用了生成器和Promise
,生成器是协程的实现,利用生成器能实现生成器函数的暂停和恢复。另外,V8引擎为async/await
做了大量的语法层面包装。
Fetch
fetch('https://www.geekbang.org')
.then((response) => {
console.log(response)
return fetch('https://www.geekbang.org/test')
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})
async/await
async function foo(){
try{
let response1 = await fetch('https://www.geekbang.org') console.log('response1')
console.log(response1)
let response2 = await fetch('https://www.geekbang.org/test') console.log('response2')
console.log(response2)
} catch(err) {
console.error(err)
}
}
foo()
生成器函数
function* genDemo() {
console.log(" 开始执行第一段 ")
yield 'generator 2'
console.log(" 开始执行第二段 ")
yield 'generator 2'
console.log(" 开始执行第三段 ")
yield 'generator 2'
console.log(" 执行结束 ")
return 'generator 2'
}
console.log('main 0')
let gen = genDemo()
console.log(gen.next().value)
console.log('main 1')
console.log(gen.next().value)
console.log('main 2')
console.log(gen.next().value)
console.log('main 3')
console.log(gen.next().value)
console.log('main 4')
生成器 + Promise
function* foo() {
let response1 = yield fetch('https://www.geekbang.org') console.log('response1')
console.log(response1)
let response2 = yield fetch('https://www.geekbang.org/test') console.log('response2')
console.log(response2)
}
// 执行 foo 函数的代码
let gen = foo()
function getGenPromise(gen) {
return gen.next().value
}
getGenPromise(gen).then((response) =>
console.log('response1')
console.log(response)
return getGenPromise(gen)
}).then((response) => {
console.log('response2')
console.log(response)
})
执行器
function* foo() {
let response1 = yield fetch('https://www.geekbang.org') console.log('response1')
console.log(response1)
let response2 = yield fetch('https://www.geekbang.org/test') console.log('response2')
console.log(response2)
}
co(foo())