面试题答案
一键面试防止不必要的异步请求
- 比较前后状态:
- 在
componentDidUpdate
中,通过比较前一个状态(prevProps
和prevState
)与当前状态(props
和state
),只有当相关数据发生变化时才触发异步请求。例如,如果异步请求依赖于某个prop
值:
componentDidUpdate(prevProps) { if (prevProps.someProp!== this.props.someProp) { // 发起异步请求 this.fetchData(); } }
- 在
- 使用防抖或节流:
- 防抖:
- 引入防抖函数,比如使用
lodash
的debounce
。它可以确保在一定时间间隔内,如果多次触发更新,只会在最后一次触发后的指定时间执行异步操作。
import React, { Component } from'react'; import { debounce } from 'lodash'; class MyComponent extends Component { constructor(props) { super(props); this.fetchDataDebounced = debounce(this.fetchData, 300); } componentDidUpdate() { this.fetchDataDebounced(); } fetchData = () => { // 异步数据获取逻辑 } componentWillUnmount() { this.fetchDataDebounced.cancel(); } }
- 引入防抖函数,比如使用
- 节流:
- 使用
lodash
的throttle
函数,它可以限制异步操作在一定时间间隔内最多执行一次。例如,设置每1秒最多执行一次异步请求。
import React, { Component } from'react'; import { throttle } from 'lodash'; class MyComponent extends Component { constructor(props) { super(props); this.fetchDataThrottled = throttle(this.fetchData, 1000); } componentDidUpdate() { this.fetchDataThrottled(); } fetchData = () => { // 异步数据获取逻辑 } componentWillUnmount() { this.fetchDataThrottled.cancel(); } }
- 使用
- 防抖:
管理异步操作的并发
- 使用AbortController(适用于fetch请求):
- 在发起
fetch
请求时,创建一个AbortController
实例。如果有新的异步请求发起,先中止之前未完成的请求。
componentDidUpdate() { if (this.abortController) { this.abortController.abort(); } this.abortController = new AbortController(); const signal = this.abortController.signal; fetch('your - api - url', { signal }) .then(response => { // 处理响应 }) .catch(error => { if (error.name === 'AbortError') { // 忽略因中止而产生的错误 } else { // 处理其他错误 } }); }
- 在发起
- 使用队列管理:
- 创建一个请求队列,当有新的异步请求时,将其加入队列。只有当前面的请求完成后,才处理队列中的下一个请求。可以使用
async/await
结合Promise
来实现。
class MyComponent extends Component { constructor(props) { super(props); this.requestQueue = []; } componentDidUpdate() { const newRequest = new Promise((resolve, reject) => { // 异步请求逻辑,完成后resolve或reject }); this.requestQueue.push(newRequest); if (this.currentRequest === null) { this.processQueue(); } } processQueue = async () => { while (this.requestQueue.length > 0) { this.currentRequest = this.requestQueue.shift(); try { await this.currentRequest; } catch (error) { // 处理错误 } finally { this.currentRequest = null; } } } }
- 创建一个请求队列,当有新的异步请求时,将其加入队列。只有当前面的请求完成后,才处理队列中的下一个请求。可以使用