ฉันจะทำให้ฟังก์ชั่นรอจนกระทั่งคำขอ jQuery Ajax ทั้งหมดเสร็จสิ้นภายในฟังก์ชั่นอื่นได้อย่างไร
กล่าวโดยย่อฉันต้องรอให้คำขอ Ajax ทั้งหมดเสร็จสิ้นก่อนที่ฉันจะดำเนินการต่อไป แต่อย่างไร
ฉันจะทำให้ฟังก์ชั่นรอจนกระทั่งคำขอ jQuery Ajax ทั้งหมดเสร็จสิ้นภายในฟังก์ชั่นอื่นได้อย่างไร
กล่าวโดยย่อฉันต้องรอให้คำขอ Ajax ทั้งหมดเสร็จสิ้นก่อนที่ฉันจะดำเนินการต่อไป แต่อย่างไร
คำตอบ:
jQuery ตอนนี้กำหนดฟังก์ชั่นเมื่อเพื่อวัตถุประสงค์นี้
มันรับจำนวนวัตถุที่รอการตัดบัญชีเป็นข้อโต้แย้งและดำเนินการฟังก์ชั่นเมื่อพวกเขาทั้งหมดแก้ไข
ซึ่งหมายความว่าหากคุณต้องการเริ่มต้น (ตัวอย่าง) คำขอ ajax สี่คำขอจากนั้นดำเนินการเมื่อเสร็จแล้วคุณสามารถทำสิ่งนี้ได้:
$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
// the code here will be executed when all four ajax requests resolve.
// a1, a2, a3 and a4 are lists of length 3 containing the response text,
// status, and jqXHR object for each of the four ajax calls respectively.
});
function ajax1() {
// NOTE: This function must return the value
// from calling the $.ajax() method.
return $.ajax({
url: "someUrl",
dataType: "json",
data: yourJsonData,
...
});
}
ในความคิดของฉันมันทำให้ไวยากรณ์ที่สะอาดและชัดเจนและหลีกเลี่ยงการเกี่ยวข้องกับตัวแปรทั่วโลกเช่น ajaxStart และ ajaxStop ซึ่งอาจมีผลข้างเคียงที่ไม่พึงประสงค์ในขณะที่หน้าของคุณพัฒนา
หากคุณไม่ทราบล่วงหน้าว่าจะต้องมีอาร์กิวเมนต์อาแจ็กซ์จำนวนเท่าใด (เช่นคุณต้องการใช้จำนวนตัวแปรที่มีข้อโต้แย้ง) ก็ยังสามารถทำได้ แต่ก็ยากกว่านิดหน่อย ดูPass ในอาร์เรย์ Deferreds เป็น $. เมื่อ () (และอาจจะjQuery. เมื่อการแก้ไขปัญหาด้วยจำนวนอาร์กิวเมนต์ที่เปลี่ยนแปลง )
หากคุณต้องการควบคุมโหมดความล้มเหลวของสคริปต์ ajax ให้ลึกซึ้งยิ่งขึ้นคุณสามารถบันทึกวัตถุที่ส่งคืนโดย.when()
- เป็นวัตถุสัญญา jQuery ซึ่งครอบคลุมคำค้นหา ajax ดั้งเดิมทั้งหมด คุณสามารถโทร.then()
หรือ.fail()
เพิ่มรายละเอียดตัวจัดการความสำเร็จ / ล้มเหลวได้
$.when
จะส่งคืนวัตถุซึ่งมีวิธีการที่เป็นประโยชน์มากขึ้นไม่เพียงPromise
.done
ตัวอย่างเช่นด้วย.then(onSuccess, onFailure)
วิธีการที่คุณสามารถตอบสนองเมื่อคำขอทั้งสองประสบความสำเร็จหรืออย่างน้อยหนึ่งข้อล้มเหลว
fail
กรณี ซึ่งแตกต่างจากdone
, fail
ไฟทันทีในครั้งแรกล้มเหลวและสภาพแวดล้อม deferreds เหลือ
onFailure
ฟังก์ชั่นสามารถแนบ ในขณะที่ฉันชี้ให้เห็นในการแสดงความคิดเห็นกับคำถามของ OP: เขาอาจต้องการระบุอย่างแม่นยำมากขึ้นว่า "เสร็จสิ้น" "ไรอันมอร์" ยังไม่มีจุดดีมากเกี่ยวกับความจริงที่ว่าfail
ทำงานแตกต่างกันเป็นdone
บางส่วนอ่านต่อไปที่จะทำเกี่ยวกับPromises
ฉันเดาhtml5rocks.com/en/tutorials/es6/promises
หากคุณต้องการทราบว่าเมื่อ ajax
คำขอทั้งหมดเสร็จสิ้นในเอกสารของคุณไม่ว่าจะมีคำขอจำนวนเท่าใดให้ใช้เหตุการณ์$ .ajaxStopด้วยวิธีนี้:
$(document).ajaxStop(function () {
// 0 === $.active
});
ในกรณีนี้คุณไม่จำเป็นต้องคาดเดาว่ามีคำขอเกิดขึ้นจำนวนเท่าใดในแอปพลิเคชันซึ่งอาจเสร็จสิ้นในอนาคตหรือขุดเป็นฟังก์ชันตรรกะที่ซับซ้อนหรือค้นหาฟังก์ชันที่ทำหน้าที่
HTTP(S)
ร้องขอ
$.ajaxStop
ที่นี่ยังสามารถผูกกับHTML
โหนดใด ๆที่คุณคิดว่าอาจถูกแก้ไขโดย requst
อัปเดต:
หากคุณต้องการติดกับES
ไวยากรณ์คุณสามารถใช้Promise.allสำหรับajax
วิธีการที่เป็นที่รู้จัก:
Promise.all([ajax1(), ajax2()]).then(() => {
// all requests finished successfully
}).catch(() => {
// all requests finished but one or more failed
})
จุดที่น่าสนใจที่นี่เป็นที่ทำงานทั้งที่มีPromises
และ$.ajax
การร้องขอ
นี่คือการสาธิตjsFiddle
อัปเดต 2:
ยังมีเวอร์ชันที่ใหม่กว่าโดยใช้ไวยากรณ์async / await :
try {
const results = await Promise.all([ajax1(), ajax2()])
// do other actions
} catch(ex) { }
ผมพบว่าคำตอบที่ดีโดยgnarfตัวเองของฉันซึ่งเป็นสิ่งที่ผมกำลังมองหา :)
jQuery ajaxQueue
//This handles the queues
(function($) {
var ajaxQueue = $({});
$.ajaxQueue = function(ajaxOpts) {
var oldComplete = ajaxOpts.complete;
ajaxQueue.queue(function(next) {
ajaxOpts.complete = function() {
if (oldComplete) oldComplete.apply(this, arguments);
next();
};
$.ajax(ajaxOpts);
});
};
})(jQuery);
จากนั้นคุณสามารถเพิ่มคำขอ ajax ในคิวดังนี้:
$.ajaxQueue({
url: 'page.php',
data: {id: 1},
type: 'POST',
success: function(data) {
$('#status').html(data);
}
});
ใช้ajaxStop
เหตุการณ์
ตัวอย่างเช่นสมมติว่าคุณมีข้อความกำลังโหลด ...ขณะดึงข้อมูลคำขอ ajax 100 รายการและคุณต้องการซ่อนข้อความนั้นเมื่อโหลด
จากเอกสาร jQuery :
$("#loading").ajaxStop(function() {
$(this).hide();
});
โปรดทราบว่ามันจะรอคำขอ ajax ทั้งหมดที่ทำในหน้านั้น
หมายเหตุ:คำตอบข้างต้นใช้ฟังก์ชั่นที่ไม่มีอยู่ในขณะที่เขียนคำตอบนี้ ฉันแนะนำให้ใช้jQuery.when()
แทนวิธีการเหล่านี้ แต่ฉันทิ้งคำตอบไว้เพื่อจุดประสงค์ทางประวัติศาสตร์
-
คุณอาจได้รับโดยการนับสัญญาณง่าย ๆ แม้ว่าวิธีที่คุณใช้มันจะขึ้นอยู่กับรหัสของคุณ ตัวอย่างง่ายๆจะเป็นสิ่งที่ชอบ ...
var semaphore = 0, // counting semaphore for ajax requests
all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts
semaphore++;
$.get('ajax/test1.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test2.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test3.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test4.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;
หากคุณต้องการให้สิ่งนี้ทำงานเหมือน {async: false} แต่คุณไม่ต้องการล็อคเบราว์เซอร์คุณสามารถทำสิ่งเดียวกันได้ด้วยคิว jQuery
var $queue = $("<div/>");
$queue.queue(function(){
$.get('ajax/test1.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test2.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test3.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test4.html', function(data) {
$queue.dequeue();
});
});
.get()
คุณควรที่จะกำหนดฟังก์ชั่นเป็นครั้งแรกแล้วอ้างอิงฟังก์ชั่นว่าในแต่ละ ด้วยวิธีนี้อย่างน้อยที่สุดคุณไม่ต้องทำซ้ำรหัสนั้น ไม่เพียงแค่นั้น แต่การประกาศfunction(){}
แต่ละครั้งจะจัดสรรหน่วยความจำในแต่ละครั้ง! ค่อนข้างจะเป็นการปฏิบัติที่ไม่ดีถ้าคุณสามารถเรียกใช้ฟังก์ชันที่กำหนดแบบคงที่
javascript เป็นไปตามเหตุการณ์ดังนั้นคุณไม่ควรรอให้ตั้ง hooks / callbacks แทน
คุณสามารถใช้วิธีการสำเร็จ / วิธีการแบบสมบูรณ์ของjquery.ajax
หรือคุณสามารถใช้. jaxComplete :
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler.');
//and you can do whatever other processing here, including calling another function...
}
});
แม้ว่าคุณควรโพสต์ pseudocode ว่าคำขอ ajax ของคุณถูกเรียกว่าแม่นยำมากกว่านี้อย่างไร
วิธีแก้ไขเล็กน้อยคืออะไรเช่นนี้:
// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
counter++;
if( counter >= ajaxCalls ) {
// When all ajax calls has been done
// Do something like hide waiting images, or any else function call
$('*').css('cursor', 'auto');
}
};
var loadPersons = function() {
// Show waiting image, or something else
$('*').css('cursor', 'wait');
var url = global.ctx + '/loadPersons';
$.getJSON(url, function(data) {
// Fun things
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCountries = function() {
// Do things
var url = global.ctx + '/loadCountries';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCities = function() {
// Do things
var url = global.ctx + '/loadCities';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
$(document).ready(function(){
loadPersons();
loadCountries();
loadCities();
});
หวังว่าจะมีประโยชน์ ...
jQuery อนุญาตให้คุณระบุว่าคุณต้องการให้ ajax ร้องขอแบบอะซิงโครนัสหรือไม่ คุณสามารถทำการร้องขอ ajax แบบซิงโครนัสแล้วส่วนที่เหลือของรหัสจะไม่ทำงานจนกว่าพวกเขาจะกลับมา
ตัวอย่างเช่น:
jQuery.ajax({
async: false,
//code
});
หากคุณต้องการอะไรที่เรียบง่าย โทรกลับครั้งเดียวแล้วเสร็จ
//multiple ajax calls above
var callback = function () {
if ($.active !== 0) {
setTimeout(callback, '500');
return;
}
//whatever you need to do here
//...
};
callback();
ฉันคิดว่ามันดีกว่า $. เมื่อคุณสามารถรวมการโทรแบบอะซิงโครนัสทุกชนิดที่ไม่รองรับสัญญานอกกรอบเช่นหมดเวลาโทร SqlLite ฯลฯ และไม่ใช่แค่การขออาแจ็กซ์
บนพื้นฐานของคำตอบ @ BBonifield ฉันเขียนฟังก์ชันยูทิลิตี้เพื่อให้สัญญาณเซมาฟอร์ไม่ได้แพร่กระจายในการโทร ajax ทั้งหมด
untilAjax
เป็นฟังก์ชั่นยูทิลิตี้ที่เรียกใช้ฟังก์ชั่นการโทรกลับเมื่อ ajaxCalls ทั้งหมดเสร็จสมบูรณ์
ajaxObjs
[http://api.jquery.com/jQuery.ajax/]
เป็นอาร์เรย์ของวัตถุการตั้งค่าอาแจ็กซ์
fn
เป็นฟังก์ชั่นการโทรกลับ
function untilAjax(ajaxObjs, fn) {
if (!ajaxObjs || !fn) {
return;
}
var ajaxCount = ajaxObjs.length,
succ = null;
for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
succ = ajaxObjs[i]['success'];
ajaxObjs[i]['success'] = function(data) { //modified success handler
if (succ) {
succ(data);
}
ajaxCount--;
if (ajaxCount == 0) {
fn(); //modify statement suitably if you want 'this' keyword to refer to another object
}
};
$.ajax(ajaxObjs[i]); //make ajax call
succ = null;
};
: ตัวอย่างการใช้งานฟังก์ชั่น doSomething
untilAjax
function doSomething() {
// variable declarations
untilAjax([{
url: 'url2',
dataType: 'json',
success: function(data) {
//do something with success data
}
}, {
url: 'url1',
dataType: 'json',
success: function(data) {
//do something with success data
}
}, {
url: 'url2',
dataType: 'json',
success: function(response) {
//do something with success data
}
}], function() {
// logic after all the calls are completed.
});
}
ฉันขอแนะนำให้ใช้$. เมื่อ ()ถ้าคุณเริ่มต้นจากศูนย์
แม้ว่าคำถามนี้จะมีคำตอบมากกว่าล้านคำตอบ แต่ฉันก็ยังไม่พบว่ามีประโยชน์กับคดี สมมติว่าคุณต้องจัดการกับ codebase ที่มีอยู่แล้วทำการโทร ajax และไม่ต้องการที่จะแนะนำความซับซ้อนของสัญญาและ / หรือทำซ้ำสิ่งทั้งหมด
เราสามารถใช้ประโยชน์จาก jQuery .data
, .on
และ.trigger
ฟังก์ชั่นที่ได้เป็นส่วนหนึ่งของ jQuery ตั้งแต่ตลอดไป
สิ่งที่ดีเกี่ยวกับโซลูชันของฉันคือ:
เห็นได้ชัดว่าการติดต่อกลับขึ้นอยู่กับอะไร
ฟังก์ชั่นtriggerNowOrOnLoaded
ไม่สนใจว่าข้อมูลถูกโหลดไปแล้วหรือเรายังรออยู่
มันง่ายมากที่จะเสียบเข้ากับโค้ดที่มีอยู่
$(function() {
// wait for posts to be loaded
triggerNowOrOnLoaded("posts", function() {
var $body = $("body");
var posts = $body.data("posts");
$body.append("<div>Posts: " + posts.length + "</div>");
});
// some ajax requests
$.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
$("body").data("posts", data).trigger("posts");
});
// doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests
$.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
$("body").data("users", data).trigger("users");
});
// wait for both types
triggerNowOrOnLoaded(["posts", "users"], function() {
var $body = $("body");
var posts = $body.data("posts");
var users = $body.data("users");
$body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
});
// works even if everything has already loaded!
setTimeout(function() {
// triggers immediately since users have been already loaded
triggerNowOrOnLoaded("users", function() {
var $body = $("body");
var users = $body.data("users");
$body.append("<div>Delayed Users: " + users.length + "</div>");
});
}, 2000); // 2 seconds
});
// helper function
function triggerNowOrOnLoaded(types, callback) {
types = $.isArray(types) ? types : [types];
var $body = $("body");
var waitForTypes = [];
$.each(types, function(i, type) {
if (typeof $body.data(type) === 'undefined') {
waitForTypes.push(type);
}
});
var isDataReady = waitForTypes.length === 0;
if (isDataReady) {
callback();
return;
}
// wait for the last type and run this function again for the rest of the types
var waitFor = waitForTypes.pop();
$body.on(waitFor, function() {
// remove event handler - we only want the stuff triggered once
$body.off(waitFor);
triggerNowOrOnLoaded(waitForTypes, callback);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>Hi!</body>
ฉันใช้การตรวจสอบขนาดเมื่อโหลด ajax ทั้งหมดเสร็จสิ้น
function get_ajax(link, data, callback) {
$.ajax({
url: link,
type: "GET",
data: data,
dataType: "json",
success: function (data, status, jqXHR) {
callback(jqXHR.status, data)
},
error: function (jqXHR, status, err) {
callback(jqXHR.status, jqXHR);
},
complete: function (jqXHR, status) {
}
})
}
function run_list_ajax(callback){
var size=0;
var max= 10;
for (let index = 0; index < max; index++) {
var link = 'http://api.jquery.com/ajaxStop/';
var data={i:index}
get_ajax(link,data,function(status, data){
console.log(index)
if(size>max-2){
callback('done')
}
size++
})
}
}
run_list_ajax(function(info){
console.log(info)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
เพื่อขยายคำตอบของอเล็กซ์ฉันมีตัวอย่างที่มีข้อโต้แย้งและสัญญา ฉันต้องการโหลดภาพผ่าน ajax และแสดงภาพบนหน้าเว็บหลังจากโหลดเสร็จแล้ว
ในการทำเช่นนั้นฉันใช้สิ่งต่อไปนี้:
let urlCreator = window.URL || window.webkitURL;
// Helper function for making ajax requests
let fetch = function(url) {
return $.ajax({
type: "get",
xhrFields: {
responseType: "blob"
},
url: url,
});
};
// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));
// Use the spread operator to wait for all requests
$.when(...files).then(function() {
// If we have multiple urls, then loop through
if(urls.length > 1) {
// Create image urls and tags for each result
Array.from(arguments).forEach(data => {
let imageUrl = urlCreator.createObjectURL(data[0]);
let img = `<img src=${imageUrl}>`;
$("#image_container").append(img);
});
}
else {
// Create image source and tag for result
let imageUrl = urlCreator.createObjectURL(arguments[0]);
let img = `<img src=${imageUrl}>`;
$("#image_container").append(img);
}
});
อัปเดตเพื่อใช้งาน URL เดียวหรือหลาย URL: https://jsfiddle.net/euypj5w9/
ตามคำตอบอื่น ๆ ที่กล่าวถึงคุณสามารถใช้ajaxStop()
เพื่อรอจนกว่าคำขอ ajax ทั้งหมดจะเสร็จสมบูรณ์
$(document).ajaxStop(function() {
// This function will be triggered every time any ajax request is requested and completed
});
หากคุณต้องการทำajax()
ตามคำขอเฉพาะสิ่งที่ดีที่สุดที่คุณสามารถทำได้คือใช้complete()
วิธีการภายในคำขอ ajax ที่แน่นอน:
$.ajax({
type: "POST",
url: "someUrl",
success: function(data) {
// This function will be triggered when ajax returns a 200 status code (success)
},
complete: function() {
// This function will be triggered always, when ajax request is completed, even it fails/returns other status code
},
error: function() {
// This will be triggered when ajax request fail.
}
});
แต่ถ้าคุณต้องรอให้ ajax เพียงไม่กี่คำร้องขอเสร็จสมบูรณ์ ใช้จาวาสคริปต์ที่ยอดเยี่ยมที่สัญญาว่าจะรอจนกว่าอาแจ็กซ์เหล่านี้ที่คุณต้องการจะเสร็จสิ้น ฉันทำตัวอย่างสั้น ๆ ง่ายและอ่านได้เพื่อแสดงให้คุณเห็นว่าสัญญาทำงานกับอาแจ็กซ์ได้อย่างไร โปรดดูตัวอย่างต่อไป
ฉันเคยsetTimeout
ชี้แจงตัวอย่าง
// Note:
// resolve() is used to mark the promise as resolved
// reject() is used to mark the promise as rejected
$(document).ready(function() {
$("button").on("click", function() {
var ajax1 = new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: "https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png",
xhrFields: { responseType: 'blob'},
success: function(data) {
setTimeout(function() {
$('#image1').attr("src", window.URL.createObjectURL(data));
resolve(" Promise ajax1 resolved");
}, 1000);
},
error: function() {
reject(" Promise ajax1 rejected");
},
});
});
var ajax2 = new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: "https://cdn1.iconfinder.com/data/icons/social-media-vol-1-1/24/_github-512.png",
xhrFields: { responseType: 'blob' },
success: function(data) {
setTimeout(function() {
$('#image2').attr("src", window.URL.createObjectURL(data));
resolve(" Promise ajax2 resolved");
}, 1500);
},
error: function() {
reject(" Promise ajax2 rejected");
},
});
});
var ajax3 = new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: "https://miro.medium.com/max/632/1*LUfpOf7teWvPdIPTBmYciA.png",
xhrFields: { responseType: 'blob' },
success: function(data) {
setTimeout(function() {
$('#image3').attr("src", window.URL.createObjectURL(data));
resolve(" Promise ajax3 resolved");
}, 2000);
},
error: function() {
reject(" Promise ajax3 rejected");
},
});
});
Promise.all([ajax1, ajax2, ajax3]).then(values => {
console.log("We waited until ajax ended: " + values);
console.log("My few ajax ended, lets do some things!!")
}, reason => {
console.log("Promises failed: " + reason);
});
// Or if you want wait for them individually do it like this
// ajax1.then(values => {
// console.log("Promise 1 resolved: " + values)
// }, reason => {
// console.log("Promise 1 failed: " + reason)
// });
});
});
img {
max-width: 200px;
max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Make AJAX request</button>
<div id="newContent">
<img id="image1" src="">
<img id="image2" src="">
<img id="image3" src="">
</div>
ฉันพบวิธีที่ง่ายมันใช้ shift()
function waitReq(id)
{
jQuery.ajax(
{
type: 'POST',
url: ajaxurl,
data:
{
"page": id
},
success: function(resp)
{
...........
// check array length if not "0" continue to use next array value
if(ids.length)
{
waitReq(ids.shift()); // 2
)
},
error: function(resp)
{
....................
if(ids.length)
{
waitReq(ids.shift());
)
}
});
}
var ids = [1, 2, 3, 4, 5];
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1
ทางออกของฉันมีดังนี้
var request;
...
'services': {
'GetAddressBookData': function() {
//This is the primary service that loads all addressbook records
request = $.ajax({
type: "POST",
url: "Default.aspx/GetAddressBook",
contentType: "application/json;",
dataType: "json"
});
},
...
'apps': {
'AddressBook': {
'data': "",
'Start': function() {
...services.GetAddressBookData();
request.done(function(response) {
trace("ajax successful");
..apps.AddressBook.data = response['d'];
...apps.AddressBook.Filter();
});
request.fail(function(xhr, textStatus, errorThrown) {
trace("ajax failed - " + errorThrown);
});
ทำงานค่อนข้างดี ฉันพยายามทำสิ่งต่าง ๆ มากมาย แต่ฉันคิดว่านี่เป็นวิธีที่ง่ายที่สุดและใช้ซ้ำได้มากที่สุด หวังว่ามันจะช่วย
ดูวิธีแก้ปัญหาของฉัน:
1. ใส่ฟังก์ชั่นนี้ (และตัวแปร) ลงในไฟล์จาวาสคริปต์ของคุณ:
var runFunctionQueue_callback;
function runFunctionQueue(f, index, callback) {
var next_index = index + 1
if (callback !== undefined) runFunctionQueue_callback = callback;
if (f[next_index] !== undefined) {
console.log(index + ' Next function avalaible -> ' + next_index);
$.ajax({
type: 'GET',
url: f[index].file,
data: (f[index].data),
complete: function() {
runFunctionQueue(f, next_index);
}
});
} else {
console.log(index + ' Last function');
$.ajax({
type: 'GET',
url: f[index].file,
data: (f[index].data),
async: false,
complete: runFunctionQueue_callback
});
}
}
2. สร้างอาร์เรย์ด้วยคำขอของคุณเช่นนี้:
var f = [
{file: 'file_path', data: {action: 'action', data: 'any_data}},
{file: 'file_path', data: {action: 'action', data: 'any_data}},
{file: 'file_path', data: {action: 'action', data: 'any_data}},
{file: 'file_path', data: {action: 'action', data: 'any_data}}
];
3. สร้างฟังก์ชั่นการโทรกลับ:
function Function_callback() {
alert('done');
}
4. เรียกใช้ฟังก์ชัน runFunctionQueue พร้อมพารามิเตอร์:
runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function
$.when
ไม่ทำงานสำหรับฉันcallback(x)
แทนที่จะreturn x
ทำงานตามที่อธิบายไว้ที่นี่: https://stackoverflow.com/a/13455253/10357604
ลองด้วยวิธีนี้ สร้าง loop ภายในฟังก์ชันจาวาสคริปต์เพื่อรอจนกระทั่งการโทร ajax เสร็จสิ้น
function getLabelById(id)
{
var label = '';
var done = false;
$.ajax({
cache: false,
url: "YourMvcActionUrl",
type: "GET",
dataType: "json",
async: false,
error: function (result) {
label='undefined';
done = true;
},
success: function (result) {
label = result.Message;
done = true;
}
});
//A loop to check done if ajax call is done.
while (!done)
{
setTimeout(function(){ },500); // take a sleep.
}
return label;
}
setTimeout()
take a sleep
ในกรณีนี้คุณเพียงปิดกั้นแท็บทั้งหมดจนกว่าdone
จะเป็นจริง
done
จะไม่เป็นจริงในขณะที่ขณะที่ลูปยังคงทำงานอยู่ หากขณะที่ลูปทำงานอยู่เหตุการณ์ลูปจะไม่สามารถดำเนินการต่อได้ดังนั้นจะไม่เรียกใช้การเรียกกลับสู่ความสำเร็จ ajax