1. 什么是Promise?
Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。
promise的作用:
- 解决回调地狱,代码易于维护
- 合并多个异步请求
Promise 会有三种状态
- 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled): 意味着操作成功完成。
- 已拒绝(rejected): 意味着操作失败。
状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected,且一但发生改变便不可二次修改;
2. 执行 async 函数,返回的都是 Promise 对象
async function test1() {
return 1
}
async function test2() {
return Promise.resolve(2)
}
const result1 = test1()
const result2 = test2()
console.log("result1:",result1);
console.log("result2:",result2);
3. Promise.then成功的情况下,对应的是await
async function test3() {
const p3 = Promise.resolve(3)
p3.then(data=>{
console.log("p3data",data);
})
// 第一种 await 后面是个Promise对象
const data1 = await p3
console.log("data1",data1);
// 第二种 await 后面是个普通的值
const data2 = await 4 // await Promise.resolve(4),自动封装成这样
console.log("data2",data2);
// 第三种 await 后面是个函数,
const data3 = await test1()
console.log("data3",data3);
}
test3()
4. Promise.catch异常的情况 对应的是try ... catch
async function test4() {
const p4 = Promise.reject(4)
try {
const data4 = await p4
console.log("data4:",data4);
} catch(e) {
console.error("e",e);
}
}
test4()
5. Promise的相关api
-
Promise.all
Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。在all方法中可以传递多个Promise对象,当所有的Promise对象状态都返回fufilled,才会返回fulfilled,否则返回rejected。
const promise1 = new Promise((resolve, reject) => {
resolve();
})
const promise2 = new Promise((resolve, reject) => {
resolve();
})
const promise3 = new Promise((resolve, reject) => {
resolve();
})
const promiseAll = Promise.all([promise1, promise2, promise3]).then(res => {
console.log('all');
})
-
Promise.race
Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。可以传递多个Promise对象作为参数,如果实例红有一个实例 率先 改变状态,那么race的状态就会跟着改变。
const promise1 = new Promise((resolve, reject) => {
reject();
})
const promise2 = new Promise((resolve, reject) => {
resolve();
})
const promise3 = new Promise((resolve, reject) => {
reject();
})
const promiseRace = Promise.race([promise1, promise2, promise3]).then(res => {
console.log('race then');
}).catch(error => {
console.log('race catch');
})
-
Promise.finally
finally方法用于指定不管Promis对象最后状态如何,都会执行的操作。
new Promise((resolve, reject) => {
resolve();
}).then(res => {
console.log('success');
}).catch(error => {
console.log('error');
}).finally(() =>{
console.log('finally');
})
6. 记录一下,猜猜他的执行顺序
console.log('111');
async function isProgress() {
let i = 0;
let timer
return new Promise((resolve)=>{
console.log('222');
timer = setInterval(()=>{
console.log('333');
i++
if(i > 3) {
clearInterval(timer)
console.log('4444');
resolve("OK")
}
},1000)
})
}
await isProgress()
console.log('555');
7. 几道面试题
1. 基础题目
const fn = () =>
new Promise((resolve, reject) => {
console.log(1);
resolve("success");
});
console.log("start");
fn().then(res => {
console.log(res);
});
解析:
new Promise()虽然是立即执行的,但是我们需要看它是否被函数包裹,此题中fn调用时才会执行new Promise(),因此start在1之前。
结果:
"start"
1
"success"
2. 结合setTimeout
Promise.resolve().then(() => {
console.log('promise1');
const timer2 = setTimeout(() => {
console.log('timer2')
}, 0)
});
const timer1 = setTimeout(() => {
console.log('timer1')
Promise.resolve().then(() => {
console.log('promise2')
})
}, 0)
console.log('start');
解析:
- 第一轮正常执行宏任务:Promise.resolve.then()放到第一轮微任务,timer1进入第二轮中的宏任务,打印出start。
- 第一轮微任务:打印promise1,再将timer2放入第三轮宏任务。
- 第二轮宏任务:打印timer1,Promise.resolve.then()进入第二轮微任务。
- 第二轮微任务:打印promise2.
- 第三轮宏任务:打印timer2
结果
'start'
'promise1'
'timer1'
'promise2'
'timer2'
3.结合then,catch
const promise = new Promise((resolve, reject) => {
reject("error");
resolve("success2");
});
promise
.then(res => {
console.log("then1: ", res);
}).then(res => {
console.log("then2: ", res);
}).catch(err => {
console.log("catch: ", err);
}).then(res => {
console.log("then3: ", res);
})
结果:
"catch: " "error"
"then3: " undefined
4. async、await
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
setTimeout(() => {
console.log('timer1')
}, 0)
}
async function async2() {
setTimeout(() => {
console.log('timer2')
}, 0)
console.log("async2");
}
async1();
setTimeout(() => {
console.log('timer3')
}, 0)
console.log("start")
解析:
在这里,你可以理解为「紧跟着await后面的语句相当于放到了new Promise中,下一行及之后的语句相当于放在Promise.then中」。
结果:
'async1 start'
'async2'
'start'
'async1 end'
'timer2'
'timer3'
'timer1'