Promise的async/await
async/await以同步的语法来编写异步代码,彻底消灭啦回调函数
function loadImg(src) {
const promise = new Promise((resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
reject(new Error(`图片加载失败 ${src}`))
}
img.src = src
})
return promise
}
async function loadImg1() {
const src1 = 'http://www.imooc.com/static/img/index/logo_new.png';
const img1 = await loadImg(src1)
return img1
}
async function loadImg2() {
const src2 = 'https://avatars3.githubusercontent.com/u/9583120';
const img2 = await loadImg(src2)
return img2
}
// 匿名函数后加括号可立即执行
(async function () {
// 注意:await 必须放在 async 函数中,否则会报错
try {
// 加载第一张图片
const img1 = await loadImg1()
// img12是一个promise对象
console.log(img1)
// 加载第二张图片
const img2 = await loadImg2()
console.log(img2)
} catch (ex) {
console.error(ex)
}
})()
//async 函数返回结果都是 Promise 对象
async function fn2() {
return new Promise(() => {})
}
console.log( fn2() )
//(如果函数内没返回 Promise ,则自动封装一下)
async function fn1() {
// 相当于return Promise.resolve(100)
return 100
}
console.log( fn1() )
//await相当于promise的then
(async function () {
const p2 = Promise.resolve(100)
const res = await p2
console.log(res) // 100
})()
//- await 后续跟非 Promise 对象:会直接返回
(async function () {
//相当于const res = await Promise.resolve(100)
const res = await 100
console.log(res) // 100
})()
//- await 后面跟 Promise 对象:会阻断后续代码,等待状态变为 resolved ,才获取结果并继续执行
(async function () {
const p1 = new Promise(() => {})
// 处于pending状态,不能执行await
await p1
console.log('p1') // 不会执行
})()
(async function () {
//注意这里Promise.reject rejected状态
const p3 = Promise.reject('some err')
//await相当于promise的then
const res = await p3 //报错 用try catch解决
console.log(res) // 不会执行
})()
// try...catch 捕获 rejected 状态
// try...catch相当于promise的catch
(async function () {
const p4 = Promise.reject('some err')
try {
const res = await p4
console.log(res)
} catch (ex) {
console.error(ex)
}
})()
//await 是同步写法,但本质还是异步调用。
async function async1 () {
console.log('async1 start') //2
await async2()
//await的后面,都可以看作是callback里的内容,即异步
//即,只要遇到了 `await` ,后面的代码都相当于放在 callback 里。
//类似event loop,setTimeout(cb1)
//类似setTimeout(function() { console.log('async1 end') })
//类似Promise.resolve.then(() => { console.log('async1 end') })
// 最后event loop执行异步
console.log('async1 end') // 5
// 关键在这一步,它相当于放在 callback 中,最后执行
}
async function async2 () {
console.log('async2') //3
}
console.log('script start') //1
async1()
console.log('script end') //4
//同步代码执行完(event loop)
再看一个(从await出现起的下一行代码全是异步)
async function async1 () {
console.log('async1 start') // 2
await async2()
// 下面三行异步,callback里的内容
console.log('async1 end') // 5
await async3()
// 下面一行是异步回调的内容
console.log('async1 end 2') // 7
}
async function async2 () {
console.log('async2') // 3
}
async function async3 () {
console.log('async3') // 6
}
console.log('script start') // 1
async1()
console.log('script end') // 4
// 定时算乘法
function multi(num) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num * num)
}, 1000)
})
}
// 使用 forEach ,是 1s 之后打印出所有结果,即 3 个值是一起被计算出来的(同步循环)
function test1 () {
const nums = [1, 2, 3];
nums.forEach(async x => {
const res = await multi(x);
console.log(res);
})
}
test1();
// 使用 for...of ,可以让计算挨个串行执行(异步循环)
async function test2 () {
const nums = [1, 2, 3];
for (let x of nums) {
// 在 for...of 循环体的内部,遇到 await 会挨个串行计算
const res = await multi(x)
console.log(res)
}
}
test2()