使用 JavaScript 的 Promise 鏈時,一個常見的陷阱是嘗試錯誤地使用 setTimeout。在下面的範例中, getLinks 函數傳回一個承諾,從提供的網址 取得一組連結:
<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中文網其他相關文章!