ฟังก์ชันเรียกกลับเป็นเพียงฟังก์ชันที่คุณส่งผ่านไปยังฟังก์ชันอื่นเพื่อให้ฟังก์ชันนั้นสามารถเรียกใช้ในภายหลังได้ นี้มีให้เห็นกันทั่วไปในตรงกันAPI s; การเรียก API จะส่งกลับทันทีเนื่องจากเป็นแบบอะซิงโครนัสดังนั้นคุณจึงส่งผ่านฟังก์ชันเข้าไปในนั้นซึ่ง API สามารถเรียกใช้เมื่อดำเนินการทำงานแบบอะซิงโครนัสเสร็จแล้ว
ตัวอย่างที่ง่ายที่สุดที่ฉันคิดได้ใน JavaScript คือsetTimeout()
ฟังก์ชัน เป็นฟังก์ชันส่วนกลางที่ยอมรับสองอาร์กิวเมนต์ อาร์กิวเมนต์แรกคือฟังก์ชันเรียกกลับและอาร์กิวเมนต์ที่สองคือความล่าช้าในหน่วยมิลลิวินาที ฟังก์ชันนี้ออกแบบมาเพื่อรอระยะเวลาที่เหมาะสมจากนั้นเรียกใช้ฟังก์ชันเรียกกลับของคุณ
setTimeout(function () {
console.log("10 seconds later...");
}, 10000);
คุณอาจเคยเห็นรหัสด้านบนมาก่อน แต่ไม่ทราบว่าฟังก์ชันที่คุณส่งผ่านนั้นเรียกว่าฟังก์ชันเรียกกลับ เราสามารถเขียนโค้ดด้านบนใหม่เพื่อให้ชัดเจนยิ่งขึ้น
var callback = function () {
console.log("10 seconds later...");
};
setTimeout(callback, 10000);
การโทรกลับถูกใช้ทั่วทุกที่ในโหนดเนื่องจากโหนดถูกสร้างขึ้นจากพื้นดินขึ้นไปเป็นแบบอะซิงโครนัสในทุกสิ่งที่ทำ แม้จะคุยกับระบบไฟล์. นั่นเป็นเหตุผลที่ Node API ภายในจำนวนมากยอมรับฟังก์ชันการเรียกกลับเป็นอาร์กิวเมนต์แทนที่จะส่งคืนข้อมูลที่คุณสามารถกำหนดให้กับตัวแปรได้ แต่จะเรียกใช้ฟังก์ชันเรียกกลับของคุณโดยส่งผ่านข้อมูลที่คุณต้องการเป็นอาร์กิวเมนต์ ตัวอย่างเช่นคุณสามารถใช้fs
ไลบรารีของ Node เพื่ออ่านไฟล์ fs
โมดูล exposes สองฟังก์ชัน API ไม่ซ้ำกัน: และreadFile
readFileSync
readFile
ฟังก์ชั่นไม่ตรงกันในขณะที่ยังreadFileSync
ไม่ชัด คุณจะเห็นว่าพวกเขาตั้งใจที่คุณใช้โทร async เมื่อใดก็ตามที่เป็นไปได้เนื่องจากพวกเขาเรียกว่าพวกเขาreadFile
และreadFileSync
แทนและreadFile
readFileAsync
นี่คือตัวอย่างของการใช้ทั้งสองฟังก์ชัน
ซิงโคร:
var data = fs.readFileSync('test.txt');
console.log(data);
รหัสดังกล่าวดำเนินการบล็อกด้ายจนเนื้อหาทั้งหมดของการอ่านในหน่วยความจำและเก็บไว้ในตัวแปรtest.txt
data
ในโหนดนี้ถือเป็นการปฏิบัติที่ไม่ดี มีหลายครั้งที่มันมีประโยชน์เช่นเมื่อเขียนสคริปต์เล็ก ๆ น้อย ๆ เพื่อทำสิ่งที่เรียบง่าย แต่น่าเบื่อและคุณไม่สนใจเกี่ยวกับการประหยัดเวลาทุก ๆ นาโนวินาทีเท่าที่จะทำได้
แบบอะซิงโครนัส (พร้อมการโทรกลับ):
var callback = function (err, data) {
if (err) return console.error(err);
console.log(data);
};
fs.readFile('test.txt', callback);
ก่อนอื่นเราสร้างฟังก์ชันเรียกกลับที่รับสองอาร์กิวเมนต์err
และdata
. ปัญหาอย่างหนึ่งของฟังก์ชันอะซิงโครนัสคือการดักจับข้อผิดพลาดทำได้ยากขึ้นดังนั้น API แบบเรียกกลับจำนวนมากจึงส่งข้อผิดพลาดเป็นอาร์กิวเมนต์แรกของฟังก์ชันเรียกกลับ แนวทางปฏิบัติที่ดีที่สุดคือตรวจสอบว่าerr
มีค่าหรือไม่ก่อนที่จะดำเนินการอย่างอื่น หากเป็นเช่นนั้นให้หยุดการเรียกกลับและบันทึกข้อผิดพลาด
การโทรแบบซิงโครนัสมีข้อได้เปรียบเมื่อมีข้อยกเว้นเนื่องจากคุณสามารถจับได้ด้วยtry/catch
บล็อก
try {
var data = fs.readFileSync('test.txt');
console.log(data);
} catch (err) {
console.error(err);
}
ในฟังก์ชันอะซิงโครนัสจะไม่ทำงานในลักษณะนั้น การเรียก API จะส่งคืนทันทีดังนั้นจึงไม่มีสิ่งใดที่จะจับกับไฟล์try/catch
. API แบบอะซิงโครนัสที่เหมาะสมซึ่งใช้การเรียกกลับจะตรวจจับข้อผิดพลาดของตนเองได้เสมอจากนั้นจึงส่งข้อผิดพลาดเหล่านั้นไปยังการเรียกกลับซึ่งคุณสามารถจัดการได้ตามที่เห็นสมควร
นอกเหนือจากการเรียกกลับแล้วยังมีอีกรูปแบบหนึ่งที่เป็นที่นิยมของ API ที่มักใช้เรียกว่าสัญญา หากคุณต้องการที่จะอ่านเกี่ยวกับพวกเขาแล้วคุณสามารถอ่านบล็อกโพสต์ทั้งหมดที่ผมเขียนอยู่บนพื้นฐานของคำตอบนี้ที่นี่