Promise?async?await?懂的都懂!!!

402 阅读3分钟

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'