Saya memiliki JavaScript widget yang menyediakan standar ekstensi poin. Salah satu dari mereka adalah beforecreate
fungsi. Itu harus kembali palsu
untuk mencegah item yang dibuat.
I've menambahkan Ajax panggilan ke fungsi ini menggunakan jQuery:
beforecreate: function (node, targetNode, type, to) {
jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
function (result) {
if (result.isOk == false)
alert(result.message);
});
}
Tapi aku ingin mencegah widget saya dari menciptakan item, jadi saya harus kembali palsu
pada ibu-fungsi, tidak di callback. Apakah ada cara untuk melakukan sinkron permintaan AJAX menggunakan jQuery atau di-browser API?
Dari jQuery dokumentasi: anda tentukan asynchronous pilihan palsu untuk mendapatkan sinkron permintaan Ajax. Kemudian anda balik dapat mengatur beberapa data sebelum ibumu fungsi hasil.
Berikut ini's apa kode anda akan terlihat seperti jika berubah seperti yang disarankan:
beforecreate: function (node, targetNode, type, to) {
jQuery.ajax({
url: 'http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
success: function (result) {
if (result.isOk == false) alert(result.message);
},
async: false
});
}
Anda dapat menempatkan jQuery's Ajax setup dalam modus sinkron dengan memanggil
jQuery.ajaxSetup({async:false});
Dan kemudian melakukan panggilan Ajax menggunakan jQuery.mendapatkan( ... );`
Kemudian menyalakannya lagi setelah
jQuery.ajaxSetup({async:true});
Saya kira itu bekerja di luar hal yang sama seperti yang disarankan oleh @Adam, tapi mungkin akan membantu untuk seseorang yang tidak ingin mengkonfigurasi mereka jQuery.get()
atau jQuery.post()
untuk yang lebih rumit jQuery.ajax()
sintaks.
Solusi yang sangat baik! Yang saya perhatikan ketika saya mencoba untuk menerapkannya bahwa jika saya kembali nilai dalam keberhasilan klausa, itu datang kembali sebagai terdefinisi. Aku harus menyimpannya dalam variabel dan kembali variabel itu. Ini adalah metode yang saya datang dengan:
function getWhatever() {
// strUrl is whatever URL you need to call
var strUrl = "", strReturn = "";
jQuery.ajax({
url: strUrl,
success: function(html) {
strReturn = html;
},
async:false
});
return strReturn;
}
Semua jawaban ini kehilangan titik yang melakukan Ajax call dengan async:palsu akan menyebabkan browser untuk menggantung sampai permintaan Ajax selesai. Menggunakan flow control perpustakaan akan memecahkan masalah ini tanpa menutup browser. Berikut ini adalah contoh dengan Frame.js:
beforecreate: function(node,targetNode,type,to) {
Frame(function(next)){
jQuery.get('http://example.com/catalog/create/', next);
});
Frame(function(next, response)){
alert(response);
next();
});
Frame.init();
}
Perlu diingat bahwa jika anda'kembali melakukan cross domain Ajax call (dengan menggunakan JSONP) - anda dapat't lakukan serentak, yang async
bendera akan diabaikan oleh jQuery.
$.ajax({
url: "testserver.php",
dataType: 'jsonp', // jsonp
async: false //IGNORED!!
});
Untuk JSONP-panggilan yang bisa anda gunakan:
Catatan: Anda tidak't menggunakan async: palsu
karena ini pesan peringatan:
Mulai dengan Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), sinkron permintaan di thread utama telah ditinggalkan karena efek negatif untuk pengalaman pengguna.
Chrome bahkan memperingatkan tentang hal ini di console:
Sinkron XMLHttpRequest di thread utama ini sudah ditinggalkan karena efek merugikan untuk pengguna akhir's pengalaman. Untuk bantuan lebih lanjut, periksa https://xhr.spec.whatwg.org/.
Ini bisa mematahkan halaman anda jika anda melakukan sesuatu seperti ini karena bisa berhenti bekerja setiap hari.
Jika anda ingin melakukannya dengan cara yang masih terasa seperti jika itu's sinkron tapi masih don't blok maka anda harus menggunakan async/menunggu dan mungkin juga beberapa ajax yang didasarkan pada janji-janji seperti baru Mengambil API
async function foo() {
var res = await fetch(url)
console.log(res.ok)
var json = await res.json()
console.log(json)
}
Edit chrome bekerja pada Pelarangan sync XHR di halaman pemecatan ketika halaman yang sedang berlayar jauh atau tertutup oleh pengguna. Ini melibatkan beforeunload, membongkar, pagehide dan visibilitychange.
jika ini adalah kasus anda maka anda mungkin ingin untuk melihat di navigator.sendBeacon bukan
Hal ini juga memungkinkan untuk halaman untuk menonaktifkan sinkronisasi req dengan baik http header atau iframe's memungkinkan atribut
Saya menggunakan jawaban yang diberikan oleh Carcione dan dimodifikasi untuk menggunakan JSON.
function getUrlJsonSync(url){
var jqxhr = $.ajax({
type: "GET",
url: url,
dataType: 'json',
cache: false,
async: false
});
// 'async' has to be 'false' for this to work
var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON};
return response;
}
function testGetUrlJsonSync()
{
var reply = getUrlJsonSync("myurl");
if (reply.valid == 'OK')
{
console.dir(reply.data);
}
else
{
alert('not valid');
}
}
Saya menambahkan dataType dari 'JSON' dan .responseText untuk responseJSON.
Saya juga diakses status menggunakan statusText properti dari objek kembali. Catatan, bahwa ini adalah status dari Ajax respon, bukan apakah JSON adalah valid.
Back-end harus mengembalikan respon yang benar (well-formed) JSON, jika tidak kembali objek akan menjadi tidak terdefinisi.
Ada dua aspek yang perlu dipertimbangkan ketika menjawab pertanyaan awal. Salah satunya adalah menceritakan Ajax untuk melakukan serentak (dengan pengaturan async: false) dan yang lain adalah kembali respon melalui pemanggilan fungsi's pernyataan return, daripada ke fungsi callback.
Saya juga mencoba dengan POSTING dan itu berhasil.
Aku berubah sampai ke POS dan ditambahkan data: postdata
function postUrlJsonSync(url, postdata){
var jqxhr = $.ajax({
type: "POST",
url: url,
data: postdata,
dataType: 'json',
cache: false,
async: false
});
// 'async' has to be 'false' for this to work
var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON};
return response;
}
Perhatikan bahwa kode di atas hanya bekerja dalam kasus di mana async adalah palsu. Jika anda adalah untuk mengatur async: true kembali objek jqxhr tidak akan berlaku pada saat AJAX panggilan kembali, hanya kemudian ketika panggilan asynchronous telah selesai, tapi itu terlalu terlambat untuk mengatur respon variabel.
Dengan async: false
anda mendapatkan diri anda diblokir browser.
Untuk non-blocking sinkron solusi anda dapat menggunakan berikut:
Dengan ES6 anda dapat menggunakan generator & co perpustakaan:
beforecreate: function (node, targetNode, type, to) {
co(function*(){
let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
//Just use the result here
});
}
Dengan ES7 anda hanya dapat menggunakan asyc menanti:
beforecreate: function (node, targetNode, type, to) {
(async function(){
let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
//Just use the result here
})();
}
Pertama-tama kita harus memahami ketika kita menggunakan $.ajax dan ketika kita menggunakan $.mendapatkan/$.posting
Ketika kita membutuhkan tingkat rendah kontrol atas permintaan ajax seperti header permintaan pengaturan, caching pengaturan, pengaturan sinkron dll.kemudian kita harus pergi untuk $.ajax.
$.mendapatkan/$.post: Ketika kita tidak memerlukan tingkat rendah kontrol atas permintaan ajax.Hanya sederhana dapatkan/mengirim data ke server.Itu adalah singkatan dari
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
dan karenanya kita tidak dapat menggunakan fitur-fitur lainnya(menyelaraskan,cache, dll.) dengan $.mendapatkan/$.post.
Oleh karena itu untuk low level control(menyelaraskan,cache,dll.) atas permintaan ajax,kita harus pergi untuk $.ajax
$.ajax({
type: 'GET',
url: url,
data: data,
success: success,
dataType: dataType,
async:false
});
ini adalah implementasi sederhana untuk ASYNC permintaan dengan jQuery. Saya harap ini membantu siapa pun.
var queueUrlsForRemove = [
'http://dev-myurl.com/image/1',
'http://dev-myurl.com/image/2',
'http://dev-myurl.com/image/3',
];
var queueImagesDelete = function(){
deleteImage( queueUrlsForRemove.splice(0,1), function(){
if (queueUrlsForRemove.length > 0) {
queueImagesDelete();
}
});
}
var deleteImage = function(url, callback) {
$.ajax({
url: url,
method: 'DELETE'
}).done(function(response){
typeof(callback) == 'function' ? callback(response) : null;
});
}
queueImagesDelete();
Karena XMLHttpReponse
operasi sinkron adalah usang saya datang dengan solusi berikut yang membungkus XMLHttpRequest
. Hal ini memungkinkan memerintahkan AJAX pertanyaan saat masih menjadi asycnronous di alam, yang sangat berguna untuk penggunaan tunggal CSRF token.
Hal ini juga transparan sehingga library seperti jQuery akan beroperasi dengan mulus.
/* wrap XMLHttpRequest for synchronous operation */
var XHRQueue = [];
var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function()
{
var xhr = new _XMLHttpRequest();
var _send = xhr.send;
xhr.send = function()
{
/* queue the request, and if it's the first, process it */
XHRQueue.push([this, arguments]);
if (XHRQueue.length == 1)
this.processQueue();
};
xhr.processQueue = function()
{
var call = XHRQueue[0];
var xhr = call[0];
var args = call[1];
/* you could also set a CSRF token header here */
/* send the request */
_send.apply(xhr, args);
};
xhr.addEventListener('load', function(e)
{
/* you could also retrieve a CSRF token header here */
/* remove the completed request and if there is more, trigger the next */
XHRQueue.shift();
if (XHRQueue.length)
this.processQueue();
});
return xhr;
};
Ini adalah saya "Benang" namespace:
var Thread = {
sleep: function(ms) {
var start = Date.now();
while (true) {
var clock = (Date.now() - start);
if (clock >= ms) break;
}
}
};
Dan ini adalah bagaimana saya menyebutnya:
var d1 = new Date();
console.log('start ' + d1.toLocaleTimeString());
Thread.sleep(10000);
var d2 = new Date();
console.log('end ' + d2.toLocaleTimeString());
Dan jika melihat konsol, kami mendapatkan hasil sebagai berikut:
start 1:41:21 PM
end 1:41:31 PM