สรุป: มีรูปแบบการปฏิบัติที่ดีที่สุดบางอย่างที่ฉันสามารถติดตามเพื่อให้โค้ดของฉันสามารถอ่านได้แม้จะใช้รหัสอะซิงโครนัสและการโทรกลับหรือไม่
ฉันใช้ไลบรารี JavaScript ที่ทำสิ่งต่างๆมากมายแบบอะซิงโครนัสและอาศัยการโทรกลับอย่างหนัก ดูเหมือนว่าการเขียนวิธี "โหลด A, โหลด B, ... " ง่าย ๆ นั้นค่อนข้างซับซ้อนและยากที่จะติดตามโดยใช้รูปแบบนี้
ขอยกตัวอย่าง (contrived) สมมติว่าฉันต้องการโหลดรูปภาพจำนวนมาก (แบบอะซิงโครนัส) จากเว็บเซิร์ฟเวอร์ระยะไกล ใน C # / async ฉันจะเขียนสิ่งนี้:
disableStartButton();
foreach (myData in myRepository) {
var result = await LoadImageAsync("http://my/server/GetImage?" + myData.Id);
if (result.Success) {
myData.Image = result.Data;
} else {
write("error loading Image " + myData.Id);
return;
}
}
write("success");
enableStartButton();
เลย์เอาต์รหัสเป็นไปตาม "การไหลของเหตุการณ์": อันดับแรกปุ่มเริ่มต้นถูกปิดใช้งานจากนั้นภาพจะถูกโหลด ( await
ทำให้แน่ใจว่า UI ยังคงตอบสนองได้) จากนั้นปุ่มเริ่มทำงานจะเปิดใช้งานอีกครั้ง
ใน JavaScript โดยใช้การโทรกลับฉันมาด้วยสิ่งนี้:
disableStartButton();
var count = myRepository.length;
function loadImage(i) {
if (i >= count) {
write("success");
enableStartButton();
return;
}
myData = myRepository[i];
LoadImageAsync("http://my/server/GetImage?" + myData.Id,
function(success, data) {
if (success) {
myData.Image = data;
} else {
write("error loading image " + myData.Id);
return;
}
loadImage(i+1);
}
);
}
loadImage(0);
ฉันคิดว่าข้อเสียคือชัดเจน: ฉันต้อง rework วนซ้ำในการเรียกซ้ำรหัสที่ควรจะถูกดำเนินการในที่สุดคือที่ไหนสักแห่งในช่วงกลางของฟังก์ชั่นรหัสเริ่มต้นการดาวน์โหลด ( loadImage(0)
) อยู่ด้านล่างสุด และโดยทั่วไปการอ่านและติดตามจะยากกว่ามาก มันน่าเกลียดและฉันไม่ชอบมัน
ฉันแน่ใจว่าฉันไม่ใช่คนแรกที่พบปัญหานี้ดังนั้นคำถามของฉันคือ: มีรูปแบบแนวปฏิบัติที่ดีที่สุดที่ฉันสามารถติดตามเพื่อให้โค้ดของฉันอ่านได้ทั้งๆที่ใช้รหัสแบบอะซิงโครนัสและการโทรกลับ
LoadImageAsync
จริงๆแล้วเป็นการเรียกไปยังExt.Ajax.request
Sencha Touch
async.waterfall
คำตอบของคุณ