สมมติว่าคุณรักษาห้องสมุดที่ exposes getData
ฟังก์ชัน ผู้ใช้ของคุณเรียกสิ่งนี้ว่ารับข้อมูลจริง: ข้อมูล
var output = getData();
Under the hood จะถูกบันทึกไว้ในไฟล์เพื่อให้คุณใช้งานgetData
โดยใช้ Node.js ในfs.readFileSync
ตัว เห็นได้ชัดทั้งคู่getData
และfs.readFileSync
เป็นฟังก์ชันการซิงค์ วันหนึ่งคุณได้รับคำสั่งให้เปลี่ยนแหล่งข้อมูลพื้นฐานเป็น repo เช่น MongoDB ซึ่งสามารถเข้าถึงได้แบบอะซิงโครนัสเท่านั้น นอกจากนี้คุณยังได้รับคำสั่งให้หลีกเลี่ยงการทำให้ผู้ใช้ของคุณgetData
ขุ่นเคืองไม่สามารถเปลี่ยน API ให้กลับมาเป็นเพียงคำสัญญาหรือเรียกร้องพารามิเตอร์การเรียกกลับ คุณมีคุณสมบัติตามข้อกำหนดทั้งสองอย่างไร
ฟังก์ชันอะซิงโครนัสโดยใช้การเรียกกลับ / สัญญาคือ DNA ของ JavasSript และ Node.js แอป JS ที่ไม่สำคัญใด ๆ อาจจะเต็มไปด้วยรูปแบบการเข้ารหัสนี้ แต่การปฏิบัตินี้สามารถนำไปสู่สิ่งที่เรียกว่าปิรามิดแห่งการลงโทษได้อย่างง่ายดาย ยิ่งไปกว่านั้นหากรหัสใด ๆ ในผู้โทรใด ๆ ในสายการโทรขึ้นอยู่กับผลลัพธ์ของฟังก์ชัน async รหัสเหล่านั้นจะต้องถูกรวมไว้ในฟังก์ชันการโทรกลับเช่นกันซึ่งเป็นการกำหนดข้อ จำกัด รูปแบบการเข้ารหัสสำหรับผู้โทร ในบางครั้งฉันพบว่าจำเป็นต้องห่อหุ้มฟังก์ชัน async (มักมีให้ในไลบรารีของบุคคลที่สาม) ลงในฟังก์ชันการซิงค์เพื่อหลีกเลี่ยงการแยกตัวประกอบซ้ำทั่วโลกจำนวนมาก การค้นหาวิธีแก้ปัญหาในเรื่องนี้มักจะลงเอยด้วยNode Fibersหรือแพ็คเกจ npm ที่ได้มาจากมัน แต่เส้นใยไม่สามารถแก้ปัญหาที่ฉันเผชิญได้ แม้แต่ตัวอย่างที่จัดทำโดยผู้เขียนของ Fibers ก็แสดงให้เห็นถึงข้อบกพร่อง:
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
เอาต์พุตจริง:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
หากฟังก์ชัน Fiber เปลี่ยนฟังก์ชั่น async เป็น sync จริงๆผลลัพธ์ควรเป็น:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main
ฉันได้สร้างตัวอย่างง่ายๆอีกอย่างในJSFiddleและกำลังมองหาโค้ดเพื่อให้ได้ผลลัพธ์ที่คาดหวัง ฉันยอมรับโซลูชันที่ใช้งานได้เฉพาะใน Node.js ดังนั้นคุณมีอิสระที่จะต้องใช้แพ็คเกจ npm ใด ๆ แม้ว่าจะไม่ทำงานใน JSFiddle ก็ตาม