คุณไม่ได้เจาะจงรหัสของคุณมากนักดังนั้นฉันจะสร้างสถานการณ์ สมมติว่าคุณมีการโทรของ ajax 10 ครั้งและคุณต้องการสะสมผลลัพธ์จากการโทรของ ajax 10 ครั้งจากนั้นเมื่อพวกเขาดำเนินการเสร็จสิ้นคุณก็ต้องการทำอะไรบางอย่าง คุณสามารถทำได้โดยการสะสมข้อมูลในอาร์เรย์และติดตามว่าข้อมูลสุดท้ายเสร็จสิ้นเมื่อใด:
เคาน์เตอร์คู่มือ
var ajaxCallsRemaining = 10;
var returnedData = [];
for (var i = 0; i < 10; i++) {
doAjax(whatever, function(response) {
returnedData.push(response);
--ajaxCallsRemaining;
if (ajaxCallsRemaining <= 0) {
}
});
}
หมายเหตุ: การจัดการข้อผิดพลาดมีความสำคัญที่นี่ (ไม่แสดงเนื่องจากเป็นเรื่องเฉพาะสำหรับวิธีการโทรของคุณโดยใช้ ajax) คุณจะต้องคิดว่าคุณจะจัดการกับกรณีนี้อย่างไรเมื่อการโทรของ ajax ไม่สำเร็จไม่ว่าจะด้วยข้อผิดพลาดหรือติดขัดเป็นเวลานานหรือหมดเวลาหลังจากผ่านไปนาน
jQuery สัญญา
เพิ่มคำตอบของฉันในปี 2014 ทุกวันนี้คำสัญญามักใช้ในการแก้ปัญหาประเภทนี้เนื่องจาก jQuery $.ajax()
ส่งคืนคำสัญญาไปแล้วและ$.when()
จะแจ้งให้คุณทราบเมื่อกลุ่มของคำสัญญาได้รับการแก้ไขทั้งหมดและจะรวบรวมผลตอบแทนให้คุณ:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
}, function() {
});
สัญญามาตรฐาน ES6
ตามที่ระบุไว้ในคำตอบของ kba : หากคุณมีสภาพแวดล้อมที่มีสัญญาดั้งเดิมในตัว (เบราว์เซอร์สมัยใหม่หรือ node.js หรือใช้ babeljs Transpile หรือใช้ polyfill คำสัญญา) คุณสามารถใช้สัญญาที่ระบุ ES6 ได้ ดูตารางนี้สำหรับการรองรับเบราว์เซอร์ สัญญาได้รับการสนับสนุนในเบราว์เซอร์ปัจจุบันเกือบทั้งหมดยกเว้น IE
หากdoAjax()
คืนคำสัญญาคุณสามารถทำได้:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
}, function(err) {
});
หากคุณจำเป็นต้องทำการดำเนินการ async ที่ไม่ใช่สัญญาให้เป็นแบบที่ส่งคืนสัญญาคุณสามารถ "ให้คำมั่นสัญญา" ได้ดังนี้:
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
จากนั้นใช้รูปแบบด้านบน:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
}, function(err) {
});
บลูเบิร์ดสัญญา
หากคุณใช้ไลบรารีที่มีคุณลักษณะมากมายเช่นไลบรารีBluebird Promiseจะมีฟังก์ชันเพิ่มเติมบางอย่างในตัวเพื่อให้ง่ายขึ้น:
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
}, function(err) {
});