携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
1.回调函数(callback)
setTimeout(() => {
// callback 函数体
}, 1000)
缺点:回调地狱,不能用try catch 捕获错误,不能return
try {
setTimeout(() => {
console.log(aa)
}, 1000)
} catch (error) {
}
//报错:Uncaught ReferenceError: aa is not defined
回调地狱的根本问题在于:
- 缺乏顺序性: 回调地狱导致的调试困难,和大脑的思维方式不符
- 嵌套函数存在耦合性,一旦有所改动,就会牵一发而动全身,即(控制反转)
- 嵌套函数过多的多话,很难处理错误
function a(functionb(){
c(function d(){
})
})
如何解决回调地狱?(看下面的方法)
2.Promise(ES6)
- Promise有三种状态:pending/reslove/reject 。pending就是未决,resolve可以理解为成功,reject可以理解为拒绝。
- 同时Promise常用的三种方法 then 表示异步成功执行后的数据状态变为reslove catch 表示异步失败后执行的数据状态变为reject all表示把多个没有关系的Promise封装成一个Promise对象使用then返回一个数组数据。
function f(){
let promise = new Promise((resolve, reject) => {
//模拟异步
setTimeout(()=>{
resolve('prom')
},1000)
})
return promise
}
function f1() {
//返回一个Promise用于下一次调用then
return f().then(data=>{
// 返回的数据用于下一次then使用
return data+'ise'
})
}
f1().then(data=>{
console.log(data)
})
console.log("hello word")
结果: hello word
promise
写成链式结构如下
new Promise((resolve, reject) => {
//模拟异步
setTimeout(()=>{
resolve('prom')
},1000)
}).then(data=>{
return data+'ise'
}).then(data=>{
console.log(data)
})
缺点:无法取消 Promise ,错误需要通过回调函数来捕获
3.Generator(生成器,es6)
- Generator(生成器)是一种有效利用内存的机制,一边循环一边计算生成数值的机制。通过配合Promise可以更加优雅的写异步代码 特点 : 可以控制函数的执行
function *fetch() {
yield ajax('XXX1', () => {})
yield ajax('XXX2', () => {})
yield ajax('XXX3', () => {})
}
let it = fetch()
let result1 = it.next()
let result2 = it.next()
let result3 = it.next()
缺点:生成器不是最完美的,它的语法让人难以理解
4.Async/await (异步等待, es7)
async、await 是异步的终极解决方案 优点:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题 缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。 函数前面加async 表示该函数是一个异步函数 await 表示等待一个异步值的到来 eg1
async function test() {
// 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
// 如果有依赖性的话,其实就是解决回调地狱的例子了
await fetch('XXX1')
await fetch('XXX2')
await fetch('XXX3')
}
异步函数可以更加方便的同Promise结合使用来书写同步代码风格的异步执行 eg2:
function f() {
return new Promise((resolve, reject) => {
setTimeout(()=>{
resolve("hello word")
},1000)
})
}
async function a(){
var data = await f();
return data;
}
a().then(data=>{
console.log(data)
})