Appearance
一、Promise的三种状态
- pending 进行中:不会触发then和catch
- resolved 成功:触发then
- rejected 失败:触发catch
二、Promise 加载图片
js
function loadImg(src) {
const p = new Promise((resolve,reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败 ${src}}`)
reject(err)
}
img.src = src
})
return p
}
const url1 = 'http://www.wensoul.com/static/img/avatar.jpg'
const url2 = 'http://www.wensoul.com/static/img/7de5437.png'
loadImg(url1).then(img1 => {
console.log(img1.width);
return img1
}).then(img1 => {
console.log(img1.height)
return loadImg(url2)
}).then(img2 => {
console.log(img2.width)
return img2
}).then(img2 => {
console.log(img2.height)
}).catch(ex => {
console.error(ex)
})三、Promise的then和catch状态的改变
- then正常返回resolved,里面有报错返回rejected
- catch正常返回resolved,里面有报错返回rejected
没有报错都是,resolved状态,执行then
1.代码示例:
js
const p1 = Promise.resolve().then(() => {
return 100;
})
console.log('p1',p1)//resolved,触发后续的then回调
p1.then(() => {
console.log('123')
})
const p2 = Promise.resolve().then(() => {
throw new Error('then error')
})
console.log('p2',p2)//rejected,触发后续catch回调
p2.then(() => {
console.log('345')//触发不了
}).catch(() => {
console.log('err',err)
})
const p3 = Promise.reject('my error').catch(err => {
console.log(err)
})
console.log('p3',p3)//resolved状态,触发then回调
p3.then(() => {
console.log(100)
})
const p4 = Promise.reject('my error').catch(err => {
throw new Error('catch err')
})
console.log('p4',p4)//rejected状态 触发catch回调
p4.then(() => {
console.log(200)
}).catch(() => {
console.log('some err')
})2.面试题示例:
js
Promise.resolve().then(() => {
console.log(1)//1
}).catch(() => {
console.log(2)
}).then(() => {
console.log(3)//3
})
// 第二题
Promise.resolve().then(() => {
console.log(1)//1
throw new Error('error1') //返回rejected状态,执行catch
}).catch(() => {
console.log(2)//2 返回resolved状态,触发then回调
}).then(() => {
console.log(3)//3
})
// 第三题
Promise.resolve().then(() => {
console.log(1) //1
throw new Error('error')
}).catch(() => {
console.log(2) //2
}).catch(() => {
console.log(3)
})四、async和await 语法
async/await 同步语法,消除回调函数
代码示例:js
function loadImg(src) {
const p = new Promise((resolve, reject) => {
const img = document.createElement('img');
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败 ${src}`)
reject(err)
}
img.src = src
})
return p
}
const url1 = 'http://www.wensoul.com/static/img/avatar.jpg'
const url2 = 'http://www.wensoul.com/static/img/7de5437.png';
async function loadImg1() {
const img1 = await loadImg(src1)
return img1
}
(async function() {
const img1 = await loadImg(src1)
console.log(img1.height,img1.width)
})()五、async/await和Promise的关系
async/await是消灭异步回调的终极武器,但和Promise并不互斥,两者相辅相成。
执行async函数,返回的是Promise对象,await相当于Promise的成功回调then,try。。。catch可捕获异常,代替了Promise的失败回调catch。
js
async function fn1() {
return 100
}
const res1 = fn1();//执行async函数,返回的是Promise对象
console.log(res1)
res1.then(data => {
console.log('data',data)//11
})
!(async function () {
const p1 = Promise.resolve(300)
const data = await p1 //await相当于Promise then
console.log('data',data)
})()
!(async function () {
const data1 = await 400;//await Promise.resolve(400)
console.log('data1',data1)//400
})()
!(async function () {
const data2 = await fn1() //fn1返回Promise对象
console.log('data2',data2)
})()
//try 。。catch捕获异常,代替了promise的catch
!(async function () {
const p4 = Promise.reject('err')
try{
const res = await p4
console.log(res)
}catch(ex){
console.log('ex',ex)
}
})()
!(async function () {
const p4 = Promise.reject('err')
const res = await p4 // 不会执行,使用try catch捕获异常
console.log('res',res)
})六、异步的本质
async/await是消灭异步回调的终极武器。js还是单线程,还得是有异步,还得是基于event loop。async/await只是一个语法糖。
示例:
js
async function async1() {
console.log('async1 start')//2
await async2()
//await行下面所有内容,都可以看做是callback里面的内容,即异步
//类似event loop,setTimeout(cb1)
//setTimeout(function () {console.log('async1 end')})
//Promise.resolve().then(() => {console.log('async1 end')})
console.log('async1 end')//5
}
async function async2() {
console.log('async2')//3
}
console.log('script start')//1
async1()//执行async1 立马执行函数体,打印async1 start
console.log('script end')//4另一种形式
js
async function async1() {
console.log('async1 start') // 2
await async2()
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