生成器函数(Generator)
generator是一个函数,有两个特征:generator由function*定义,并且除了return语句,还可以用yield返回多次
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator(); // elloWorldGenerator {<suspended>}
直接调用Generator函数,返回一个指向内部状态的指针对象;必须调用遍历器对象的next方法,使指针状态移动
yeild表达式暂停执行的标记,next方法可以恢复执行
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false } // done属性为false 表示遍历没有完成
hw.next()
// { value: ending, done: true } // done属性为true 表示遍历已经完成
hw.next()
// { value: undefined, done: true }
-
generator的异步方案const fetch = require('node-fetch') function* gen() { const url = 'https://es6.ruanyifeng.com/#docs/generator-async' const result = yield fetch(url) console.log(result) } const g = gen() const result = g.next() console.log(result) // { value: Promise { <pending> }, done: false } result.value.then((data) => data.size).then((data) => g.next(data))
Async/Await函数
async函数将generator函数的星号(*)替换为async,将yeild替换为await
async函数返回为Promise对象,使用then方法添加回调函数;函数执行一旦遇到await就先返回,等待异步操作完成,再接着执行函数体内后面的语句
async/await是generator的语法糖,将generator函数和自动执行器,包装在一个函数里
function co (generator) {
const g = generator()
function handleResult(result) {
if (result.down) return // 生成器函数结束
result.value.then(data = > {
// 递归调用直到执行完毕
handleResult(g.next(data))
}, error => g.throw(error))
}
handleResult(g.next())
}
function *main() {
try {
const users = yield ajax('/api/users.json')
console.log(users)
const posts = yield ajax('/api/posts.json')
console.log(posts)
const urls = yield ajax('/api/urls.json')
console.log(urls)
} catch (e) {
console.log(e)
}
}
co(main)
async function main() {
try {
const users = await ajax('/api/users.json')
console.log(users)
const posts = await ajax('/api/posts.json')
console.log(posts)
const urls = await ajax('/api/urls.json')
console.log(urls)
} catch (e) {
console.log(e)
}
}
const promise = main()
promise.then(() => {
console.log('all completed')
})
使用注意:
-
await命令后的Promise对象,运行结果可能是reject,最好将await放在try...catch中 -
多个
await命令后的异步操作,如果不存在继发关系,最好同时触发let [foo, bar] = await Promise.all([getFoo(), getBar()]) -
await命令只能用在async中
function ajax(url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response)
} else {
reject(new Error(xhr.statusText))
}
}
xhr.send()
})
}
async function main() {
try {
const users = await ajax('/api/users.json')
console.log(users)
const posts = await ajax('/api/posts.json')
console.log(posts)
const urls = await ajax('/api/urls.json')
console.log(urls)
} catch (e) {
console.log(e)
}
}
async与Promise、generator相比实现最简洁,最符合语义










网友评论