Apabila menggunakan rantai janji JavaScript, perangkap biasa cuba menggunakan setTimeout secara salah. Dalam contoh di bawah, fungsi getLinks mengembalikan janji yang mengambil set pautan daripada URL yang disediakan:
<code class="javascript">function getLinks(url) { return new Promise((resolve, reject) => { // ...XHR logic to fetch links... }); }</code>
Seterusnya, panggilan getLinks lain mendapatkan semula kandungan pautan pertama:
<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>
Walau bagaimanapun, kod ini menyebabkan ralat penghuraian JSON (JSON.parse: aksara tidak dijangka...). Sebabnya terletak pada penggunaan setTimeout yang tidak betul:
Rantai janji ialah satu siri operasi tak segerak yang dilaksanakan secara berurutan. Setiap operasi (atau kemudian pengendali) mengembalikan janji. Akibatnya, setiap pengendali kemudiannya diluluskan hasil janji sebelumnya.
Panggil balik setTimeout dilaksanakan secara tak segerak, bukan sebagai sebahagian daripada rantai janji. Mengembalikan nilai daripada panggilan balik setTimeout tidak akan mengembalikan nilai daripada pengendali ketika itu. Sebaliknya, nilai mesti dikembalikan sebelum pengendali kemudian selesai.
Untuk menangguhkan pelaksanaan janji berikutnya dalam rantai janji, seseorang perlu mengembalikan janji daripada pengendali ketika itu yang menyelesaikan selepas kelewatan yang diingini:
<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>
Fungsi kelewatan boleh dilaksanakan seperti berikut:
<code class="javascript">function delay(t, val) { return new Promise((resolve) => setTimeout(resolve, t, val)); }</code>
Sebagai alternatif, seseorang boleh mentakrifkan kaedah sambungan pada Janji untuk memudahkan sintaks:
<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>
Pendekatan ini memastikan rantaian janji kekal utuh dan operasi seterusnya dilaksanakan seperti yang diharapkan.
Atas ialah kandungan terperinci Mengapakah `setTimeout` Menyebabkan Ralat Parse JSON dalam Rantai Janji?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!