前端技巧(前端面试高频考点!Promise核心知识与手写技巧大公开)

前端技巧(前端面试高频考点!Promise核心知识与手写技巧大公开)
前端面试高频考点!Promise核心知识与手写技巧大公开

Promise是JavaScript异步处理的核心解决方案,解决了回调地狱问题,也是前端面试高频考点。它有三个状态:等待中(pending)、已完成(fulfilled)、已失败(rejected)。状态一旦从pending转为fulfilled或rejected就不可变更,即使后续再调用resolve或reject也无效;如果执行器函数中出现错误或throw,会自动触发reject。

手写Promise的第一步是实现构造函数。构造函数接收一个执行器函数,初始化状态为pending、结果为null,然后执行器函数传入resolve和reject方法。resolve和reject方法要先判断状态是否为pending,确保状态只能修改一次。比如用class定义MyPromise,构造函数内用try-catch捕获执行器的错误,触发reject:class MyPromise { constructor(excutor) { this.initValue(); try { excutor(this.resolve, this.reject); } catch (err) { this.reject(err.message); } } initValue = () => { this.PromiseState = 'pending'; this.PromiseResult = null; this.callbacks = []; } resolve = (value) => { if (this.PromiseState !== 'pending') return; this.PromiseState = 'fulfilled'; this.PromiseResult = value; this.callbacks.forEach(item => item.onResolved()); } reject = (reason) => { if (this.PromiseState !== 'pending') return; this.PromiseState = 'rejected'; this.PromiseResult = reason; this.callbacks.forEach(item => item.onRejected()); } }

then方法是Promise链式调用的核心,接收成功和失败回调。如果回调不是函数,要做默认处理:成功回调默认返回值,失败回调默认抛出错误。then返回新的Promise,根据上一个then的返回值决定状态:如果返回Promise,新Promise的状态由它决定;否则直接resolve返回值。pending状态时,要把回调存到队列,等状态变更后执行。比如MyPromise的then方法实现:Promise.prototype.then = function (onResolved, onRejected) { if (typeof onResolved !== 'function') onResolved = value => value; if (typeof onRejected !== 'function') onRejected = reason => { throw reason; }; let that = this; return new MyPromise((resolve, reject) => { function callback(type) { try { let result = type(that.PromiseResult); if (result instanceof MyPromise) { result.then(resolve, reject); } else { resolve(result); } } catch (e) { reject(e); } } if (this.PromiseState === 'fulfilled') { setTimeout(() => callback(onResolved)); } if (this.PromiseState === 'rejected') { setTimeout(() => callback(onRejected)); } if (this.PromiseState === 'pending') { this.callbacks.push({ onResolved: () => setTimeout(() => callback(onResolved)), onRejected: () => setTimeout(() => callback(onRejected)) }); } }); }

常见工具函数中,模拟微队列要区分环境:Node用process.nextTick,浏览器用MutationObserver,fallback用setTimeout。判断是否为Node环境检查process.nextTick,浏览器检查MutationObserver。函数逻辑:function microTask(fn) { if (typeof process !== 'undefined' && typeof process.nextTick === 'function') { process.nextTick(fn); } else if (typeof MutationObserver === 'function') { const observer = new MutationObserver(fn); const textNode = document.createTextNode('1'); observer.observe(textNode, { characterData: true }); textNode.data = '2'; } else { setTimeout(fn); } }

前端技巧(前端面试高频考点!Promise核心知识与手写技巧大公开)

判断PromiseLike不能用instanceof,因为iframe中的Promise实例不同。正确方法是检查值是否有then方法且为函数:function isPromiseLike(value) { return typeof value === 'object' && value !== null && typeof value.then === 'function'; }

Promise的静态方法如all接收可迭代对象,所有Promise成功才返回结果数组,顺序和输入一致;race返回第一个完成的Promise状态。实际开发中,常用来封装API请求,比如小程序的request封装:const request = (params) => { return new Promise((resolve, reject) => { wx.request({ ...params, success: res => resolve(res.data), fail: err => reject(err) }); }); } 这样调用时用async/await更简洁。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有

相关阅读

最新文章

热门文章

本栏目文章