JavaScript の Promise チェーンを利用する場合、一般的な落とし穴は、setTimeout を誤って使用しようとすることです。以下の例では、getLinks 関数は、指定された URL からリンクのセットをフェッチする Promise を返します:
<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 チェーンは、順番に実行される一連の非同期操作です。各操作 (またはハンドラー) は 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 中国語 Web サイトの他の関連記事を参照してください。