1 callback
代码:
function sleepByCb(cb) {
setTimeout(function () {
cb()
}, 1000)
}
function testCb() {
console.log('开始输出')
sleepByCb(function () {
console.log('1s后输出')
sleepByCb(function () {
console.log('2s后输出')
sleepByCb(function () {
console.log('3s后输出')
sleepByCb(function () {
console.log('4s后输出')
sleepByCb(function () {
console.log('5s后输出')
})
})
})
})
})
console.log('立即输出')
}
testCb()
testCb()
输出:
开始输出
立即输出
1s后输出
2s后输出
3s后输出
4s后输出
5s后输出
总结: 使用回调简单粗暴,但是对于回调嵌套回调的情况下,简直是没办法看
2 promise
代码:
function sleepByPromise() {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
}, 1000)
})
}
function testPromise() {
console.log('开始输出:promise')
sleepByPromise()
.then(function () {
console.log('1s后输出')
return sleepByPromise()
})
.then(function () {
console.log('2s后输出')
return sleepByPromise()
})
.then(function () {
console.log('3s后输出')
return sleepByPromise()
})
.then(function () {
console.log('4s后输出')
return sleepByPromise()
})
.then(function () {
console.log('5s后输出')
return sleepByPromise()
})
console.log('立即输出')
}
testPromise()
输出:
开始输出:promise
立即输出
1s后输出
2s后输出
3s后输出
4s后输出
5s后输出
总结: 这种链式的写法让函数的流程比较清楚了,抛弃了嵌套。但并没有解决回调本身。
3 generator
代码:
function sleepByPromise() {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
}, 1000)
})
}
function testPromise() {
console.log('开始输出:promise')
sleepByPromise()
.then(function () {
console.log('1s后输出')
return sleepByPromise()
})
.then(function () {
console.log('2s后输出')
return sleepByPromise()
})
.then(function () {
console.log('3s后输出')
return sleepByPromise()
})
.then(function () {
console.log('4s后输出')
return sleepByPromise()
})
.then(function () {
console.log('5s后输出')
return sleepByPromise()
})
console.log('立即输出')
}
// testPromise()
// 3 generator
function sleepByPromise() {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
}, 1000)
})
}
function* testGenerator() {
console.log('开始输出:generator')
yield sleepByPromise()
console.log('1s后输出')
yield sleepByPromise()
console.log('2s后输出')
yield sleepByPromise()
console.log('3s后输出')
yield sleepByPromise()
console.log('4s后输出')
yield sleepByPromise()
console.log('5s后输出')
console.log('立即输出')
}
let it = testGenerator()
it.next().value
.then(() => {
return it.next().value
})
.then(() => {
return it.next().value
})
.then(() => {
return it.next().value
})
.then(() => {
return it.next().value
})
.then(() => {
return it.next().value
})
输出:
开始输出:generator
1s后输出
2s后输出
3s后输出
4s后输出
5s后输出
立即输出
总结: 使用generator+promise使异步更像是同步(具有流程性),但是还是需要自己调用遍历比较繁琐。使用TJ大神的co库可以不用自己手动进行下一次遍历。
4 generator+co
代码:
const co = require("co");
// 同上
co(testGenerator())
输出:
开始输出:generator
1s后输出
2s后输出
3s后输出
4s后输出
5s后输出
立即输出
5 async/await
代码:
// 5 async/await
function sleepByPromise() {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
}, 1000)
})
}
async function testAsyncAwait() {
console.log('开始输出:generator')
await sleepByPromise()
console.log('1s后输出')
await sleepByPromise()
console.log('2s后输出')
await sleepByPromise()
console.log('3s后输出')
await sleepByPromise()
console.log('4s后输出')
await sleepByPromise()
console.log('5s后输出')
console.log('立即输出')
}
testAsyncAwait()
输出:
开始输出:async/await
1s后输出
2s后输出
3s后输出
4s后输出
5s后输出
立即输出
总结: 这个只是generator+promise的语法糖,但它能将原本异步的代码写成同步的形式