使用 JavaScript 的 Promise 链时,一个常见的陷阱是尝试错误地使用 setTimeout。在下面的示例中, getLinks 函数返回一个承诺,从提供的 URL 获取一组链接:
<code class="javascript">function getLinks(url) { return new Promise((resolve, reject) => { // ...XHR logic to fetch links... }); }</code>
随后,另一个 getLinks 调用检索第一个链接的内容:
<code class="javascript">getLinks('links.txt') .then((links) => { const allLinks = JSON.parse(links); return getLinks(allLinks["one"] + ".txt"); }) .then((topic) => { // ...logic to write topic to body... setTimeout(() => { return getLinks(allLinks["two"] + ".txt"); // This is where the error occurs }, 1000); });</code>
但是,此代码会导致 JSON 解析错误(JSON.parse:意外字符...)。原因在于 setTimeout 使用不当:
Promise 链是一系列顺序执行的异步操作。每个操作(或处理程序)都会返回一个承诺。因此,每个 then 处理程序都会传递前一个 Promise 的结果。
setTimeout 回调是异步执行的,而不是作为 Promise 链的一部分。从 setTimeout 回调返回值不会从 then 处理程序返回值。相反,该值必须在 then 处理程序完成之前返回。
要延迟 Promise 链中后续 Promise 的执行,需要从 then 处理程序返回一个 Promise在所需的延迟后解析:
<code class="javascript">... .then((topic) => { writeToBody(topic); // Replace the setTimeout call with a delay promise return delay(1000).then(() => { return getLinks(allLinks["two"] + ".txt"); }); });</code>
延迟函数可以实现如下:
<code class="javascript">function delay(t, val) { return new Promise((resolve) => setTimeout(resolve, t, val)); }</code>
或者,可以在 Promise 上定义一个扩展方法来简化语法:
<code class="javascript">Promise.prototype.delay = function(t) { return this.then((val) => { return delay(t, val); }); } ... .then((topic) => { writeToBody(topic); return delay(1000).delay(500); });</code>
这种方法确保 Promise 链保持完整,并且后续操作按预期执行。
以上是为什么 `setTimeout` 会导致 Promise 链中 JSON 解析错误?的详细内容。更多信息请关注PHP中文网其他相关文章!