回调地狱
回调地狱 简单说,就是函数作为参数层层嵌套
在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,
如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱
解决1 拆解 function 将各步拆解为单个的 function
function buildCatList(list, returnVal, fn) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
fn(catList)
}, 200, returnVal)
}
buildCatList('', 'Panther', getJanguar)
function getJanguar(list) {
buildCatList(list, 'Janguar', getLynx)
}
function getLynx(list) {
buildCatList(list, 'Lion', print)
}
function print(list) {
console.log(list)
}
解决2 通过 Promise 链式调用的方式
function buildCatList(list, returnVal) {
return new Promise(function (resolve, reject) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
resolve(catList)
}, 200, returnVal)
})
}
buildCatList('', 'Panther').then(function (res) {
return buildCatList(res, 'Janguar')
}).then(function (res) {
return buildCatList(res, 'Lion')
}).then(function (res) {
console.log(res)
})
解决4 async / await
function buildCatList(list, returnVal) {
return new Promise(function (resolve, reject) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
resolve(catList)
}, 200, returnVal)
})
}
function fn(list) {
return list + ',' + 555
}
async function render() {
var a = await buildCatList('','Panther')
var b = await buildCatList(a, 'Jaguar')
var c = await buildCatList(b, 'Lion')
var d = await fn(c)
console.log(d) // Panther,Jaguar,Lion,555
}
render()
function hell(arg) {
return new Promise((resolve, reject) => {
setTimeout(()=>{
var val
if(!arg) val = '1'
else val = arg
resolve(arg + 1)
},1000)
})
}
function fn(arg) {
return arg + ',' + 'end'
}
async function render() {
var a = await hell('2')
var b = await hell(a)
var c = await hell(b)
var d = await fn(c)
console.log(d)
}
render()
async/await
-
async 可以把普通的函数改成异步函数,调用都是一样的,返回的是一个promise对象
-
async配合await使用是一个阻塞的异步方法
async
返回一个promise对象, 无论函数内部是否有await都会返回promise对象
函数内部return返回的值, 会成为then回调函数的第一个参数
函数内部如果出现错误,会被then的第二个参数或catch所捕获
await
只能在async函数中出现, 普通函数直接使用会报错
正常情况下, await后面是一个Promise对象, 返回该对象的结果.
如果await后面不是Promise对象, 就直接返回对应的值