Promise 是 JavaScript 中的一种异步编程解决方案,它可以避免回调地狱,提高代码可读性和可维护性。在 Promise 中,then 方法是非常重要的一个方法,它可以让我们在 Promise 状态改变时执行相应的操作。本文将介绍 Promise 的 then 方法实现原理,帮助读者更好地理解 Promise。
Promise 状态
在了解 Promise 的 then 方法实现原理之前,我们需要先了解 Promise 的状态。Promise 有三种状态:
- pending:初始状态,既不是成功也不是失败状态。
- fulfilled:意味着操作成功完成。
- rejected:意味着操作失败。
Promise 状态只能从 pending 转变为 fulfilled 或 rejected,状态一旦转变就不会再改变。
Promise 的 then 方法
Promise 的 then 方法接收两个参数,第一个参数是成功时的回调函数,第二个参数是失败时的回调函数。then 方法返回一个新的 Promise 对象,可以通过该对象进行链式调用。
promise.then(onFulfilled, onRejected);
当 Promise 状态为 fulfilled 时,会调用 onFulfilled 回调函数;当 Promise 状态为 rejected 时,会调用 onRejected 回调函数。then 方法返回的新 Promise 对象的状态和值取决于 onFulfilled 或 onRejected 的返回值。
then 方法实现原理
Promise 的 then 方法的实现原理其实并不复杂,主要是利用了回调函数的机制。我们可以通过手动实现一个简单的 Promise 类来了解其实现原理。
// javascriptcn.com 代码示例 class MyPromise { constructor(executor) { this.status = 'pending'; this.value = undefined; this.reason = undefined; this.onFulfilledCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; this.onFulfilledCallbacks.forEach((callback) => callback()); } }; const reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach((callback) => callback()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { const newPromise = new MyPromise((resolve, reject) => { if (this.status === 'fulfilled') { setTimeout(() => { try { const value = onFulfilled(this.value); resolve(value); } catch (error) { reject(error); } }, 0); } else if (this.status === 'rejected') { setTimeout(() => { try { const reason = onRejected(this.reason); reject(reason); } catch (error) { reject(error); } }, 0); } else if (this.status === 'pending') { this.onFulfilledCallbacks.push(() => { setTimeout(() => { try { const value = onFulfilled(this.value); resolve(value); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const reason = onRejected(this.reason); reject(reason); } catch (error) { reject(error); } }, 0); }); } }); return newPromise; } }
在上述代码中,我们定义了一个 MyPromise 类,它有一个 then 方法用于注册回调函数。当 Promise 状态为 fulfilled 或 rejected 时,我们会执行相应的回调函数,并根据回调函数的返回值设置新 Promise 对象的状态和值。当 Promise 状态为 pending 时,我们将回调函数加入到队列中,等待 Promise 状态改变时再执行。
示例代码
下面是一个使用 Promise 的示例代码,它使用 Promise 实现了一个异步加载图片的功能。
// javascriptcn.com 代码示例 function loadImage(src) { return new Promise((resolve, reject) => { const image = new Image(); image.onload = () => { resolve(image); }; image.onerror = () => { reject(new Error('Failed to load image')); }; image.src = src; }); } loadImage('https://picsum.photos/200/300') .then((image) => { document.body.appendChild(image); }) .catch((error) => { console.error(error); });
在上述代码中,我们定义了一个 loadImage 函数,它返回一个 Promise 对象。当图片加载成功时,我们调用 resolve 方法将 Promise 状态设置为 fulfilled,并传递图片对象;当图片加载失败时,我们调用 reject 方法将 Promise 状态设置为 rejected,并传递错误对象。在 then 方法中,我们可以获取到图片对象并将其添加到页面中;在 catch 方法中,我们可以获取到错误对象并打印错误信息。
总结
本文介绍了 Promise 的 then 方法实现原理,通过手动实现了一个简单的 Promise 类来了解其实现原理。在实际开发中,我们可以直接使用 JavaScript 内置的 Promise 类,避免重复造轮子。掌握 Promise 的 then 方法实现原理可以帮助我们更好地理解 Promise,从而更好地使用 Promise。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/655dd397d2f5e1655d81d48d