likes
comments
collection
share

面试必考题:你知道Promise吗?

作者站长头像
站长
· 阅读数 54

前言

今天我们聊聊前端必学,面试必考的Promise。

异步

在聊Promise之前,我们先聊聊什么是异步。异步是指在程序执行过程中,某个操作不会阻塞后续代码的执行,而是在后台进行,当该操作完成后通过某种方式(如回调函数、事件等)通知程序其他部分。在异步操作中,程序无需等待这个操作完成就可以继续执行其他任务。常见的异步操作包括网络请求、文件读取和写入、定时器等。我们用定时器来模拟一个异步情景出来。

function foo(){
    setTimeout(()=>{
        console.log('wzm');
    },1000)
}
function bar(){
    console.log('xxj');
}

foo()
bar()

可以看到先打印的xxj,一秒之后再打印的wzm。分析一下,代码先执行foo函数,然后执行bar,但是是bar先打印,而不是等foo执行完毕,再打印bar,这种情况就是异步,foo也叫异步代码,bar叫同步代码。异步可以提高程序的效率和响应性,避免因为某个耗时操作而导致整个程序长时间处于等待状态,从而可以更好地利用系统资源和提升用户体验。

Promise

promise是前端中常用于处理异步的一种操作。上面提到异步常用于网络请求中,由于发送请求需要耗时,当一个变量存在对请求返回出来的数据引用但是还没有拿到时,由于异步的特性,代码会继续执行,那么这个变量就会为空,所以会报错。我们用定时器来模拟发送请求。

let data = null;
function a(){
    setTimeout(()=>{//模拟异步发送请求
        data = {
            name:'wzm'
        }
    },1000)
}
function b(){
    console.log(data.name);//Cannot read properties of null (reading 'name')
    at b
}
a();
b();

在以前通常的解决办法就是将b函数放在a函数里面调用,这个叫代码回调。这样确实可以解决问题,但是带来了一个新的问题,当大量使用回调函数来处理异步操作,会导致代码中出现多层嵌套的回调函数,使得代码的可读性和可维护性变差,这个就叫回调地狱,而Promise就是用来解决以上问题的。他有三种状态,分别是pending(进行中)、fulfilled(已成功)、rejected(已失败)。

使用方法

非常简单,通常使用 new Promise() 来创建,在构造函数中接收一个执行函数,该执行函数包含两个参数,分别是用于将 Promise 状态改为成功的 resolve 函数和改为失败的 reject 函数。然后可以通过 thencatch 来处理相应的结果。then():用于添加当 Promise 成功时执行的回调函数。catch():用于添加当 Promise 失败时执行的回调函数。

const promise = new Promise((resolve, reject) => {
  // 异步操作
  if (/* 操作成功 */) {
    resolve('成功的值');//这里通常放的是请求到的数据
  } else {
    reject('失败的原因');
  }
});
promise.then((resolve) => {
    console.log(resolve);//成功的值
}).catch((reject) => {
    console.log(reject);//失败的原因
})

Promise的一些方法

Promise.all()

接收一个 Promise 数组。当所有这些 Promise 都成功时,它返回一个新的 Promise,新 Promise 成功时的值是所有这些 Promise 成功值组成的数组;只要有一个 Promise 失败,整个 Promise.all 就会立即失败。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("test 1");
  }, 1000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("tset 2");
  }, 2000);
});

Promise.all([promise1, promise2])
  .then(res => {
    console.log(res); // [ 'test 1', 'tset 2' ]
  })
  .catch(error => {
    console.error(error); // 处理任何一个Promise失败的情况
  });

Promise.race()

接收一个 Promise 数组。它返回的 Promise 会在这些数组中的任意一个 Promise 状态确定(无论是成功还是失败)时就立即确定,其结果就是那个第一个确定状态的 Promise 的结果。状态确定指的是fulfilled(已成功),也就是说我们可以用它做代码优化,当我们可以从a,b接口中都能获取数据时,可以用这个方法判断a接口和b接口谁快,谁快用哪个。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("test 1");
  }, 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("test 2");
  }, 1000);
});

Promise.race([promise1, promise2])
  .then(res => {
    console.log(res); // 第一个完成的Promise的结果
  })
  .catch(error => {
    console.error(error); // 处理第一个失败的Promise的情况
  });

总结

今天我们聊了什么是Promise,他是用于处理异步的一种操作,主要可以更清晰地管理和组织异步代码的流程,使代码结构更清晰,逻辑更易于理解。我们还聊了Promise 的使用方法以及其身上的两个方法,分别是 race 和 all 。

转载自:https://juejin.cn/post/7374297192129740839
评论
请登录