直接調用(異步調異步)
function fn1() {
setTimeout(() => {
console.log('fn1執行')
fn2('fn1傳遞過去的參數')
}, 1000)
}
function fn2(data) {
setTimeout(() => {
console.log('fn2執行', data)
fn3('fn2傳遞過去的參數')
}, 1000)
}
function fn3(data) {
setTimeout(() => {
console.log('fn3執行', data)
}, 1000)
}
fn1()
執行結果如下:
我們發現這種方式雖然能實現,但是代碼量一旦變多,可讀性就降低了。
Promise的方式
function fn1() {
return new Promise((resolve, reject) => {
console.log('fn1執行')
setTimeout(() => {
console.log('fn1結束')
resolve('fn1傳遞過去的參數')
}, 1000)
})
}
function fn2(data) {
return new Promise((resolve, reject) => {
console.log('fn2執行,接收的參數', data)
setTimeout(() => {
resolve('fn2傳遞過去的參數')
}, 1000)
})
}
function fn3(data) {
return new Promise((resolve, reject) => {
console.log('fn3執行,接收的參數', data)
setTimeout(() => {
resolve('fn3傳遞過去的參數')
}, 1000)
})
}
fn1().then(fn2).then(fn3).then(res => {
console.log('最后一個', res)
})
生成器的方式
生成器就是能返回一個迭代器的函數,它也是一個函數,對比普通的函數,多了一個*,在它的函數體內可以使用yield關鍵字,函數會在每個yield后暫停,等待,直到這個生成的對象,調用下一個next(),每調用一次next會往下執行一次yieId,然后暫停。
function* main() {
const res1 = yield fn1('開始')
const res2 = yield fn2(res1)
const res3 = yield fn3(res2)
console.log(res3, '全部執行完畢')
}
const task = main()
task.next()
function fn1(data) {
setTimeout(() => {
console.log('fn1執行', data)
task.next('fn1執行完畢')
}, 1000)
}
function fn2(data) {
setTimeout(() => {
console.log('fn2執行', data)
task.next('fn2執行完畢')
}, 1000)
}
function fn3(data) {
setTimeout(() => {
console.log('fn3執行', data)
task.next('fn3執行完畢')
}, 1000)
}
console.log('我是最開始同步執行的')