这是新的一年的开始,虽然很多人都承诺要更加活跃,但我将向您展示如何让 变得更懒惰…… s,即。 Promise JavaScript Promise 稍后会更有意义。 https://www.youtube.com/watch?v=qj7diPVWTqY?embedable=true 首先,让我们看一个基本的 示例。在这里,我有一个名为 sleep 的函数,它需要以毫秒为单位的时间和一个值。它返回一个承诺,该承诺将执行一个 我们应该等待的毫秒数;然后 Promise 使用值解析。 Promise setTimeout /** * @template ValueType * @param {number} ms * @param {ValueType} value * @returns {Promise<ValueType>} */ function sleep(ms, value) { return new Promise((resolve) => { setTimeout(() => resolve(value), ms); }); } 它是这样工作的: 我们可以使用参数 和 等待 函数,一秒钟后, 将记录字符串 'Yawn & stretch'。 1000 'Yawn & stretch' sleep console 这没什么特别的。它的行为可能与您预期的一样,但是如果我们将它存储为变量以 稍后使用,而不是立即 返回的 ,它会变得有点奇怪。 await await Promise const nap = sleep(1000, 'Yawn & stretch') 现在,假设我们做一些其他需要时间的工作(比如输入下一个示例),然后 变量。 await nap 您可能希望在解析之前延迟一秒钟,但实际上它会立即解析。任何时候你创建一个 ,你实例化它负责的任何异步功能。 Promise 在我们的示例中,当我们定义 变量时,就会创建执行 的 。因为我打字慢,所以 会在我们 它的时候解决。 nap setTimeout Promise Promise await 换句话说, 是渴望的。他们不会等你 他们。 Promise await 在某些情况下,这是一件好事。在其他情况下,它可能会导致不必要的资源使用。对于这些场景,您可能想要一些看起来像 的东西,但使用 仅在需要时实例化。 Promise 惰性评价 在我们继续之前,我想向您展示一些有趣的东西。 并不是 JavaScript 中唯一可以 的东西。如果我们使用 方法创建一个普通 ,我们实际上可以像任何 一样 该对象。 Promise await .then() Object Promise await 这有点奇怪,但它也允许我们创建 像 的不同对象,但实际上不是。这些对象有时被称为“ “。 看起来 Promise 然后能 考虑到这一点,让我们创建一个新的 称为 ,它扩展了内置的 构造函数。扩展 Promise 并不是绝对必要的,但它使它看起来更类似于使用 之类的 。 班级 LazyPromise Promise instanceof Promise class LazyPromise extends Promise { /** @param {ConstructorParameters<PromiseConstructor>[0]} executor */ constructor(executor) { super(executor); if (typeof executor !== 'function') { throw new TypeError(`LazyPromise executor is not a function`); } this._executor = executor; } then() { this.promise = this.promise || new Promise(this._executor); return this.promise.then.apply(this.promise, arguments); } } 要关注的部分是 方法。它劫持了标准 的默认行为,等待 方法执行后再创建真正的 。 then() Promise .then() Promise 这避免了在您实际调用它之前实例化异步功能。无论您显式调用 还是使用 ,它都有效。 .then() await 现在,让我们看看如果将原始 函数中的 替换为 会发生什么。我们再次将结果分配给 变量。 sleep Promise LazyPromise nap function sleep(ms, value) { return new LazyPromise((resolve) => { setTimeout(() => resolve(value), ms); }); } const nap = sleep(1000, 'Yawn & stretch') 然后我们花时间输入 行并执行它。 await nap 这一次,无论变量创建后经过了多长时间,我们都会看到在 解析之前有一秒钟的延迟。 Promise (请注意,此实现仅创建一次新的 并在后续调用中引用它。因此,如果我们再次 它,它将像任何普通的 一样立即解析) Promise await Promise 当然,这是一个简单的示例,您可能不会在生产代码中找到它,但是有许多项目使用延迟评估的 的对象。可能最常见的示例是数据库 和查询构建器,例如 或者 . Promise ORM Knex.js 棱镜 考虑下面的伪代码。它的灵感来自其中一些查询构建器: const query = db('user') .select('name') .limit(10) const users = await query 我们创建一个数据库查询,该查询转到 表并选择前十个条目并返回它们的名称。从理论上讲,这对于常规的 可以正常工作。 "user" Promise 但是如果我们想根据查询字符串参数等特定条件修改查询怎么办?能够在最终等待 之前继续修改查询会很好。 Promise const query = db('user') .select('name') .limit(10) if (orderBy) { query.orderBy(orderBy) } if (limit) { query.limit(limit) } if (id) { query.where({ id: id }) } const users = await query 如果原始数据库查询是一个标准的 ,它会在我们分配变量后立即实例化查询,我们以后将无法修改它。 Promise 通过惰性求值,我们可以编写这样更容易理解的代码,改善开发人员体验,并且只在需要时执行一次查询。 这是惰性评估很棒的一个例子。它也可能对构建、修改和编排 HTTP 请求等有用。 Lazy 对于正确的用例来说非常酷,但这并不是说它们应该取代每个 。在某些情况下,尽快实例化并尽快准备好响应是有益的。 Promise Promise 这是另一种“视情况而定”的情况。但是下次有人要你做一个 时,考虑一下偷懒 (͡° ͜ʖ ͡°)。 Promise 非常感谢您的阅读。如果您喜欢这篇文章,请 .这是支持我的最好方式之一。你也可以 或者 如果您想知道新文章何时发布。 分享它 注册我的时事通讯 在推特上关注我 最初发表于 austingil.com .