# async/await
# 使用规则
凡是在前面添加了async的函数在执行后都会自动返回一个Promise对象
注意重点: 返回结果为Promise。
async function test() {
return 100;
}
console.log(test()) // Promise {<resolved>: 100}
await必须在async函数里使用,不能单独使用
async function test() {
let result = await Promise.resolve('success')
console.log(result)
}
test()
await后面需要跟Promise对象,不然就没有意义,而且await后面的Promise对象不必写then,因为await的作用之一就是获取后面Promise对象成功状态传递出来的参数。
function fn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
})
})
}
async function test() {
let result = await fn() //因为fn会返回一个Promise对象
console.log(result) //这里会打出Promise成功后传递过来的'success'
}
test()
# 同步与异步
在async
函数中使用await
,那么await
这里的代码就会变成同步的了,意思就是说只有等await
后面的Promise
执行完成得到结果才会继续下去,await
就是等待,这样虽然避免了异步,但是它也会阻塞代码,所以使用的时候要考虑周全。
function fn(name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${name}成功`)
}, 1000)
})
}
async function test() {
let p1 = await fn('小红')
let p2 = await fn('小明')
let p3 = await fn('小华')
return [p1, p2, p3]
}
test().then(result => {
console.log(result)
}).catch(result => {
console.log(result) // 错误的处理方法,前提是函数调用,否则往下看
})
这样写虽然是可以的,但是这里await
会阻塞代码,每个await
都必须等后面的fn()
执行完成才会执行下一行代码,所以test
函数执行需要3秒。如果不是遇到特定的场景,最好还是不要这样用。
# 优雅的错误处理方法
一般情况下async/await
在错误处理方面,主要使用 try/catch
,像这样
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('fetch data is me')
}, 1000)
})
}
(async () => {
try {
const data = await fetchData()
console.log('data is ->', data)
} catch(err) {
console.log('err is ->', err)
}
})()
# 一个适合使用async/await的业务场景
在前端编程中,我们偶尔会遇到这样一个场景:我们需要发送多个请求,而后面请求的发送总是需要依赖上一个请求返回的数据。
对于这个问题,我们既可以用的Promise
的链式调用来解决,也可以用async/await
来解决,然而后者会更简洁些。
使用Promise链式调用来处理:
function request(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
request(500).then(result => {
console.log(result) // 500
return request(result + 1000)
}).then(result => {
console.log(result) // 1500
return request(result + 1000)
}).then(result => {
console.log(result) // 2500
}).catch(error => {
console.log(error)
})
使用async/await的来处理:
function request(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
async function getResult() {
let p1 = await request(500)
let p2 = await request(p1 + 1000)
let p3 = await request(p2 + 1000)
return p3
}
getResult().then(result => {
console.log(result) // 2500
}).catch(error => {
console.log(error)
})
相对于使用then
不停地进行链式调用, 使用async/await
会显的更加易读一些。
# 在循环中使用await
如果在是循环中使用await
,就需要牢记一条:必须在async
函数中使用。
let times = [1000, 500, 2000]
async function test() {
let result = []
for (let item of times) {
let temp = await request(item)
result.push(temp)
}
return result
}
test().then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
# 测试
console.log(1)
let promiseDemo = new Promise((resolve, reject) => {
console.log(2)
setTimeout(() => {
let random = Math.random()
if (random >= 0.2) {
resolve('success')
console.log(3)
} else {
reject('failed')
console.log(3)
}
}, 1000)
})
console.log(8)
async function test() {
console.log(4)
let result = await promiseDemo
return result
}
setTimeout(() => {
console.log(7)
}, 0)
test().then(result => {
console.log(5)
}).catch((result) => {
console.log(5)
})
console.log(6)
// 1 2 8 4 6 7 3 5
← Promise 回调 跨域 →