Tampaknya sebagian besar orang melakukan permintaan asinkron dengan XMLHttpRequest, tetapi fakta bahwa ada kemampuan untuk melakukan permintaan sinkron menunjukkan mungkin ada alasan yang valid untuk melakukannya. Jadi, apa alasan yang valid itu?
javascript
ajax
Darrell Brogdon
sumber
sumber
Jawaban:
Saya pikir mereka mungkin menjadi lebih populer seiring kemajuan standar HTML 5. Jika aplikasi web diberi akses ke pekerja web, saya dapat memperkirakan pengembang menggunakan pekerja web khusus untuk membuat permintaan sinkron, seperti yang dikatakan Jonathan, untuk memastikan satu permintaan terjadi sebelum yang lain. Dengan situasi saat ini dari satu utas, ini adalah desain yang kurang ideal karena diblokir hingga permintaan selesai.
sumber
XHR sinkron berguna untuk menyimpan data pengguna. Jika Anda menangani
beforeunload
acara tersebut, Anda dapat mengunggah data ke server saat pengguna menutup halaman.Jika ini dilakukan dengan menggunakan opsi async, maka halaman bisa ditutup sebelum permintaan selesai. Melakukan ini secara sinkron memastikan permintaan selesai atau gagal dengan cara yang diharapkan.
sumber
Memperbarui:
Di bawah ini mengisyaratkan - tetapi tidak berhasil menyampaikan - bahwa dengan munculnya penanganan permintaan asinkron yang lebih baik, sebenarnya tidak ada alasan untuk menggunakan permintaan sinkron, kecuali jika bermaksud untuk dengan sengaja memblokir pengguna agar tidak melakukan apa pun sampai permintaan selesai - terdengar berbahaya: )
Meskipun, ini mungkin terdengar buruk, ada kalanya penting bahwa permintaan (atau serangkaian permintaan) terjadi sebelum pengguna meninggalkan halaman, atau sebelum tindakan dilakukan - memblokir eksekusi kode lain (misalnya, mencegah tombol kembali) dapat kemungkinan mengurangi kesalahan / pemeliharaan untuk sistem yang dirancang dengan buruk ; Yang mengatakan, saya belum pernah melihatnya di alam liar dan menekankan bahwa hal itu harus dihindari.
Library, seperti promise , berpura-pura sinkronisitas dengan proses merangkai melalui callback. Ini sesuai dengan sebagian besar kebutuhan pengembangan di mana keinginannya adalah untuk memesan, acara non-pemblokiran yang memungkinkan browser mempertahankan daya tanggap pengguna (UX yang baik).
Sebagai dinyatakan dalam dokumen Mozilla ada kasus di mana Anda harus menggunakan permintaan sinkron; Namun, tercantum juga solusi yang menggunakan beacon (tidak tersedia di IE / Safari) untuk kasus seperti itu. Sementara ini eksperimental, jika itu pernah mencapai penerimaan standar, itu mungkin bisa menempatkan paku di peti mati permintaan sinkron.
Anda ingin melakukan panggilan sinkron dalam segala jenis pemrosesan seperti transaksi, atau di mana pun urutan operasi diperlukan.
Misalnya, Anda ingin menyesuaikan acara agar Anda keluar setelah memutar lagu. Jika operasi logout terjadi lebih dulu, maka lagu tersebut tidak akan pernah dimainkan. Ini membutuhkan sinkronisasi permintaan.
Alasan lain adalah saat bekerja dengan WebService, terutama saat melakukan matematika di server.
Ada beberapa kali panggilan sinkron dapat dibenarkan dalam contoh dunia nyata yang umum. Mungkin saat mengklik login dan kemudian mengklik bagian situs yang mengharuskan pengguna untuk login.
Seperti yang dikatakan orang lain, itu akan mengikat browser Anda, jadi jauhi itu di mana Anda bisa.
Namun, alih-alih panggilan sinkron, sering kali pengguna ingin menghentikan peristiwa yang sedang dimuat dan kemudian melakukan operasi lain. Di satu sisi, ini adalah sinkronisasi, karena acara pertama ditutup sebelum acara kedua dimulai. Untuk melakukan ini, gunakan metode abort () pada objek koneksi xml.
sumber
Saya akan mengatakan bahwa jika Anda mempertimbangkan untuk memblokir browser pengguna saat permintaan selesai dapat diterima, maka pastikan menggunakan permintaan sinkron.
Jika serialisasi permintaan adalah tujuan Anda, maka ini dapat dicapai menggunakan permintaan async, dengan mengaktifkan callback onComplete dari permintaan Anda sebelumnya di baris berikutnya.
sumber
Ada banyak kasus dunia nyata di mana pemblokiran UI merupakan perilaku yang diinginkan.
Ambil aplikasi dengan beberapa bidang dan beberapa bidang harus divalidasi oleh panggilan xmlhttp ke server jarak jauh yang menyediakan sebagai masukan nilai bidang ini dan nilai bidang lainnya.
Dalam mode sinkron, logikanya sederhana, pemblokiran yang dialami pengguna sangat singkat dan tidak ada masalah.
Dalam mode async, pengguna dapat mengubah nilai bidang lain saat yang awal sedang divalidasi. Perubahan ini akan memicu panggilan xmlhttp lain dengan nilai dari bidang awal yang belum divalidasi. Apa yang terjadi jika validasi awal gagal? Kekacauan murni. Jika mode sinkronisasi tidak digunakan lagi dan dilarang, logika aplikasi menjadi mimpi buruk untuk ditangani. Pada dasarnya aplikasi harus ditulis ulang untuk mengelola kunci (mis. Menonaktifkan item lain selama proses validasi). Kompleksitas kode meningkat pesat. Gagal melakukannya dapat menyebabkan kegagalan logika dan pada akhirnya merusak data.
Pada dasarnya pertanyaannya adalah: apa yang lebih penting, pengalaman UI yang tidak diblokir atau risiko korupsi data? Jawabannya harus tetap pada pengembang aplikasi, bukan W3C.
sumber
Saya dapat melihat penggunaan permintaan XHR sinkron yang akan digunakan saat sumber daya di lokasi variabel harus dimuat sebelum sumber daya statis lainnya di halaman yang bergantung pada sumber daya pertama untuk berfungsi penuh. Faktanya, saya menerapkan permintaan XHR semacam itu di sub-proyek kecil saya sendiri sedangkan sumber daya JavaScript berada di lokasi variabel di server tergantung pada serangkaian parameter tertentu. Sumber daya JavaScript berikutnya bergantung pada sumber daya variabel tersebut dan file semacam itu HARUS dijamin untuk dimuat sebelum file tepercaya lainnya dimuat, sehingga membuat aplikasi menjadi utuh.
Landasan ide itu benar-benar berkembang pada jawaban vol7ron. Prosedur berbasis transaksi benar-benar satu-satunya waktu di mana permintaan sinkron harus dibuat. Dalam kebanyakan kasus lain, panggilan asinkron adalah alternatif yang lebih baik di mana, setelah panggilan, DOM diperbarui seperlunya. Dalam banyak kasus, seperti sistem berbasis pengguna, Anda mungkin memiliki fitur tertentu yang dikunci untuk "pengguna yang tidak sah" hingga mereka, per se, masuk. Fitur tersebut, setelah panggilan asinkron, dibuka kuncinya melalui prosedur pembaruan DOM.
Saya akhirnya harus mengatakan bahwa saya setuju dengan sebagian besar poin individu tentang masalah ini: sedapat mungkin, permintaan XHR sinkron harus dihindari karena, dengan cara kerjanya, browser terkunci dengan panggilan sinkron. Saat menerapkan permintaan sinkron, permintaan tersebut harus dilakukan dengan cara di mana browser biasanya dikunci, bagaimanapun, katakanlah di bagian HEAD sebelum pemuatan halaman benar-benar terjadi.
sumber
Pada 2015 aplikasi javascript desktop menjadi lebih populer. Biasanya dalam aplikasi tersebut saat memuat file lokal (dan memuatnya menggunakan XHR adalah opsi yang benar-benar valid), kecepatan muat sangat cepat sehingga tidak ada gunanya memperumit kode dengan async. Tentu saja mungkin ada kasus di mana asinkron adalah cara yang harus dilakukan (meminta konten dari internet, memuat file yang sangat besar atau sejumlah besar file dalam satu batch), tetapi sebaliknya sinkronisasi berfungsi dengan baik (dan jauh lebih mudah digunakan) .
sumber
jQuery menggunakan AJAX sinkron secara internal dalam beberapa keadaan. Saat memasukkan HTML yang berisi script, browser tidak akan mengeksekusinya. Skrip harus dijalankan secara manual. Skrip ini mungkin melampirkan penangan klik. Asumsikan pengguna mengklik sebuah elemen sebelum handler dipasang dan halaman tidak akan berfungsi sebagaimana mestinya. Oleh karena itu untuk mencegah kondisi balapan, AJAX sinkron akan digunakan untuk mengambil skrip tersebut. Karena AJAX sinkron secara efektif memblokir yang lainnya, dapat dipastikan bahwa skrip dan peristiwa dijalankan dalam urutan yang benar.
sumber
Alasan:
Katakanlah Anda memiliki aplikasi ajax yang perlu melakukan setengah lusin http untuk memuat berbagai data dari server sebelum pengguna dapat melakukan interaksi apa pun.
Jelas Anda ingin ini dipicu dari onload.
Panggilan sinkron berfungsi sangat baik untuk ini tanpa kerumitan tambahan pada kode. Ini sederhana dan lugas.
Kekurangan:
Satu-satunya kelemahan adalah browser Anda terkunci hingga semua data dimuat atau terjadi batas waktu. Adapun aplikasi ajax yang dimaksud, ini tidak terlalu menjadi masalah karena aplikasi tidak berguna sampai semua data awal dimuat.
Alternatif?
Namun banyak browser mengunci semua jendela / tab ketika javascript sibuk di salah satu dari mereka, yang merupakan masalah desain browser yang bodoh - tetapi sebagai akibatnya memblokir pada jaringan yang mungkin lambat menjadi tidak sopan jika mencegah pengguna menggunakan tab lain sambil menunggu halaman ajax dimuat.
Namun, sepertinya sinkronisasi telah dihapus atau dibatasi dari browser terbaru. Saya tidak yakin apakah itu karena seseorang memutuskan bahwa mereka selalu jahat, atau jika penulis browser bingung dengan WC Working Draft tentang topik tersebut.
http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method membuatnya tampak seperti (lihat bagian 4.7.3) Anda tidak diizinkan untuk menyetel batas waktu saat menggunakan mode pemblokiran . Tampaknya berlawanan dengan intuisi bagi saya: Setiap kali seseorang memblokir IO, itu sopan untuk menetapkan waktu tunggu yang wajar, jadi mengapa mengizinkan pemblokiran io tetapi tidak dengan waktu tunggu yang ditentukan pengguna?
Pendapat saya, pemblokiran IO memiliki peran penting dalam beberapa situasi tetapi harus dilaksanakan dengan benar. Meskipun tidak dapat diterima untuk satu tab atau jendela browser untuk mengunci semua tab atau jendela lain, itu adalah cacat desain browser. Malu di mana rasa malu itu karena. Tetapi sangat dapat diterima dalam beberapa kasus untuk tab atau jendela individual menjadi non-responsif selama beberapa detik (yaitu menggunakan pemblokiran IO / HTTP GET) dalam beberapa situasi - misalnya, pada pemuatan halaman, mungkin banyak data perlu dilakukan sebelum apa pun bisa dilakukan. Terkadang kode pemblokiran yang diterapkan dengan benar adalah cara terbersih untuk melakukannya.
Tentu saja fungsi yang setara dalam hal ini dapat diperoleh dengan menggunakan http asynchronous, tetapi rutinitas konyol seperti apa yang diperlukan?
Saya kira saya akan mencoba sesuatu seperti ini:
Saat memuat dokumen, lakukan hal berikut: 1: Siapkan 6 variabel flag "Selesai" global, yang diinisialisasi ke 0. 2: Jalankan semua 6 background get (Dengan asumsi urutan tidak menjadi masalah)
Kemudian, callback penyelesaian untuk masing-masing dari 6 http get akan menyetel flag "Selesai" masing-masing. Selain itu, setiap callback akan memeriksa semua flag done lainnya untuk melihat apakah semua 6 HTTP telah selesai. Callback terakhir yang harus diselesaikan, setelah melihat bahwa semua yang lain telah selesai, kemudian akan memanggil fungsi init REAL yang kemudian akan mengatur semuanya, sekarang setelah semua data diambil.
Jika urutan pengambilan penting - atau jika server web tidak dapat menerima beberapa permintaan pada saat yang sama - Anda akan membutuhkan sesuatu seperti ini:
Dalam onload (), http get pertama akan diluncurkan. Dalam callbacknya, yang kedua akan diluncurkan. Dalam callback-nya, yang ketiga - dan seterusnya, dengan setiap callback meluncurkan HTTP GET berikutnya. Ketika yang terakhir kembali, maka itu akan memanggil rutin init () yang sebenarnya.
sumber
Apa yang terjadi jika Anda melakukan panggilan sinkron dalam kode produksi?
Langit jatuh.
Tidak serius, pengguna tidak menyukai browser yang terkunci.
sumber
Saya menggunakannya untuk memvalidasi nama pengguna, selama pemeriksaan bahwa nama pengguna belum ada.
Saya tahu akan lebih baik melakukan itu secara asinkron, tetapi kemudian saya harus menggunakan kode yang berbeda untuk aturan validasi khusus ini. Saya menjelaskan lebih baik. Setup validasi saya menggunakan beberapa fungsi validasi, yang mengembalikan true atau false, tergantung apakah datanya valid.
Karena fungsinya harus kembali, saya tidak bisa menggunakan teknik asynchronous, jadi saya hanya membuat sinkronis itu dan berharap server akan menjawab cukup cepat agar tidak terlalu terlihat. Jika saya menggunakan callback AJAX, maka saya harus menangani sisa eksekusi secara berbeda dari metode validasi lainnya.
sumber
false
) dan hanya menyetelnya ke benar atau salah ketika server merespons. pada pergantian bidang Anda mengatur ulang bendera dan memanggil server lagi.Terkadang Anda memiliki tindakan yang bergantung pada orang lain. Misalnya, tindakan B hanya bisa dimulai jika A sudah selesai. Pendekatan sinkron biasanya digunakan untuk menghindari kondisi balapan . Terkadang menggunakan panggilan sinkron adalah implementasi yang lebih sederhana, lalu membuat logika kompleks untuk memeriksa setiap status panggilan asinkron Anda yang bergantung satu sama lain.
Masalah dengan pendekatan ini adalah Anda "memblokir" browser pengguna hingga tindakan selesai (hingga permintaan kembali, selesai, dimuat, dll). Jadi berhati-hatilah saat menggunakannya.
sumber
Saya menggunakan panggilan sinkron saat mengembangkan kode- apa pun yang Anda lakukan saat permintaan sedang dalam perjalanan ke dan dari server dapat mengaburkan penyebab kesalahan.
Ketika berfungsi, saya membuatnya asynchronous, tetapi saya mencoba memasukkan timer yang dibatalkan dan panggilan balik yang gagal, karena Anda tidak pernah tahu ...
sumber
SYNC vs ASYNC: Apakah perbedaannya?
Pada dasarnya intinya adalah ini:
console.info('Hello, World!'); doSomething(function handleResult(result) { console.info('Got result!'); }); console.info('Goodbye cruel world!');
Ketika
doSomething
adalah sinkron ini akan mencetak:Sebaliknya, jika
doSomething
adalah asynchronous , ini akan mencetak:Karena fungsinya
doSomething
melakukan pekerjaannya secara asinkron, ia kembali sebelum pekerjaan selesai. Jadi kami hanya mendapatkan hasilnya setelah mencetakGoodbye cruel world!
Jika kita bergantung pada hasil panggilan asynch, kita perlu menempatkan kode tergantung di callback:
console.info('Hello, World!'); doSomething(function handleResult(result) { console.info('Got result!'); if (result === 'good') { console.info('I feel great!'); } else { console.info('Goodbye cruel world!'); } });
Dengan demikian, fakta bahwa 2 atau tiga hal perlu terjadi secara berurutan bukanlah alasan untuk melakukannya secara sinkron (meskipun kode sinkronisasi lebih mudah untuk dikerjakan oleh kebanyakan orang).
MENGAPA MENGGUNAKAN SYNCHRONOUS XMLHTTPREQUEST?
Ada beberapa situasi di mana Anda membutuhkan hasil sebelum fungsi yang dipanggil selesai. Pertimbangkan skenario ini:
function lives(name) { return (name !== 'Elvis'); } console.info('Elvis ' + (lives('Elvis') ? 'lives!' : 'has left the building...');
Misalkan kita tidak memiliki kendali atas kode panggilan (
console.info
baris) dan perlu mengubah fungsilives
untuk bertanya ke server ... Tidak mungkin kita dapat melakukan permintaan asinkron ke server dari dalamlives
dan masih memiliki respons sebelumlives
selesai. Jadi kami tidak akan tahu apakah akan kembalitrue
ataufalse
. Satu-satunya cara untuk mendapatkan hasil sebelum fungsi selesai adalah dengan melakukan permintaan sinkron.Seperti yang
Sami Samhuri
disebutkan dalam jawabannya, skenario yang sangat nyata di mana Anda mungkin memerlukan jawaban atas permintaan server Anda sebelum fungsi Anda berakhir adalahonbeforeunload
peristiwa, karena ini adalah fungsi terakhir dari aplikasi Anda yang akan berjalan sebelum jendela ditutup.SAYA TIDAK PERLU PANGGILAN SINKRONISASI, TETAPI SAYA MENGGUNAKANNYA SEBAGAI MUDAH
Tolong jangan. Panggilan sinkron mengunci browser Anda dan membuat aplikasi terasa tidak responsif. Tapi kamu benar. Kode Async lebih sulit. Namun demikian, ada cara untuk membuatnya lebih mudah. Tidak semudah menyinkronkan kode, tetapi semakin mendekati: Promise s.
Berikut ini contohnya: Dua panggilan asinkron harus diselesaikan dengan sukses sebelum segmen kode ketiga dapat berjalan:
var carRented = rentCar().then(function(car){ gasStation.refuel(car); }); var hotelBooked = bookHotel().then(function(reservation) { reservation.confirm(); }); Promise.all([carRented, hotelBooked]).then(function(){ // At this point our car is rented and our hotel booked. goOnHoliday(); });
Berikut adalah cara Anda menerapkan
bookHotel
:function bookHotel() { return new Promise(function(resolve, reject){ if (roomsAvailable()) { var reservation = reserveRoom(); resolve(reservation); } else { reject(new Error('Could not book a reservation. No rooms available.')); } }); }
Lihat juga: Menulis JavaScript yang Lebih Baik dengan Janji .
sumber
XMLHttpRequest
secara tradisional digunakan untuk permintaan asynchronous. Terkadang (untuk debugging, atau logika bisnis tertentu) Anda ingin mengubah semua / beberapa panggilan asinkron dalam satu halaman untuk disinkronkan.Anda ingin melakukannya tanpa mengubah semua yang ada di kode JS Anda. Bendera async / sync memberi Anda kemampuan itu, dan jika dirancang dengan benar, Anda hanya perlu mengubah satu baris dalam kode Anda / mengubah nilainya
var
selama waktu eksekusi.sumber
Firefox (dan kemungkinan semua browser non-IE) tidak mendukung timeOut XHR asinkron.
HTML5 WebWorkers mendukung waktu tunggu. Jadi, Anda mungkin ingin menggabungkan permintaan XHR sinkronisasi ke WebWorker dengan waktu tunggu untuk mengimplementasikan XHR seperti asinkron dengan perilaku waktu tunggu.
sumber
Saya baru saja mengalami situasi di mana permintaan asinkron untuk daftar url yang dipanggil berturut-turut menggunakan forEach (dan perulangan for) akan menyebabkan permintaan yang tersisa dibatalkan. Saya beralih ke sinkron dan berfungsi sebagaimana mestinya.
sumber
Menggunakan permintaan HTTP sinkron adalah praktik umum dalam bisnis periklanan seluler.
Perusahaan (alias "Penerbit") yang membuat aplikasi sering kali menjalankan iklan untuk menghasilkan pendapatan. Untuk ini, mereka memasang SDK iklan ke dalam aplikasi mereka. Banyak yang ada (MoPub, Ogury, TapJob, AppNext, Google Ads AdMob).
SDK ini akan menayangkan iklan dalam tampilan web.
Saat menayangkan iklan kepada pengguna, itu harus menjadi pengalaman yang lancar , terutama saat memutar video. Seharusnya tidak ada buffering atau pemuatan setiap saat.
Untuk mengatasi ini
precaching
digunakan. Dimana media (gambar / video / dll) dimuat secara sinkron di latar belakang tampilan web.Mengapa tidak melakukannya secara asinkron?
onload
peristiwa tersebut untuk mengetahui kapan iklan "siap" untuk ditayangkan kepada penggunaDengan penghentian XMLHttpRequests sinkron , bisnis iklan kemungkinan besar akan dipaksa untuk mengubah standar di masa mendatang kecuali cara lain dapat ditentukan.
sumber
Synchronous XHR bisa sangat berguna untuk alat internal (non-produksi) dan / atau pengembangan kerangka kerja. Bayangkan, misalnya, Anda ingin memuat pustaka kode secara sinkron pada akses pertama, seperti ini:
get draw() { if (!_draw) { let file; switch(config.option) { case 'svg': file = 'svgdraw.js'; break; case 'canvas': file = 'canvasdraw.js'; break; default: file = 'webgldraw.js'; } var request = new XMLHttpRequest(); request.open('GET', file, false); request.send(null); _draw = eval(request.responseText); } return _draw; }
Sebelum Anda menjadi bingung dan secara membabi buta memuntahkan eval dari kejahatan, perlu diingat bahwa ini hanya untuk pengujian lokal. Untuk build produksi, _draw sudah disetel.
Jadi, kode Anda mungkin terlihat seperti ini:
foo.drawLib.draw.something(); //loaded on demand
Ini hanyalah satu contoh dari sesuatu yang tidak mungkin dilakukan tanpa sinkronisasi XHR. Anda dapat memuat pustaka ini di awal, ya, atau melakukan janji / panggilan balik, tetapi Anda tidak dapat memuat lib secara sinkron tanpa sinkronisasi XHR. Pikirkan tentang seberapa banyak hal semacam ini dapat membersihkan kode Anda ...
Batasan untuk apa yang dapat Anda lakukan dengan ini untuk perkakas dan kerangka kerja (berjalan secara lokal) hanya dibatasi oleh imajinasi Anda. Padahal, tampaknya imajinasi agak terbatas di dunia JavaScript.
sumber
Nah, inilah satu alasan bagus. Saya ingin melakukan permintaan http, tergantung pada hasilnya, panggil click () pada input type = file. Ini tidak mungkin dengan xhr atau fetch asinkron. Callback kehilangan konteks "tindakan pengguna", sehingga panggilan click () diabaikan. Xhr sinkron menyimpan bacon saya.
onclick(event){ //here I can, but I don't want to. //document.getElementById("myFileInput").click(); fetch("Validate.aspx", { method : "POST", body: formData, credentials: "include" }) .then((response)=>response.json()) .then(function (validResult) { if (validResult.success) { //here, I can't. document.getElementById("myFileInput").click(); } }); }
sumber