jQuery: Kembalikan data setelah panggilan ajax berhasil

Saya memiliki sesuatu seperti ini, di mana itu adalah panggilan sederhana ke skrip yang memberi saya kembali nilai, sebuah string ..

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {
         return data; 
      }
   });
}

tetapi jika saya memanggil sesuatu seperti ini

var output = testAjax(svar);  // output will be undefined...

jadi bagaimana saya bisa mengembalikan nilainya? kode di bawah ini sepertinya juga tidak berfungsi...

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {

      }
   });
   return data; 
}
Mengomentari pertanyaan (2)

Catatan: Jawaban ini ditulis pada Februari 2010.
Lihat pembaruan dari tahun 2015, 2016 dan 2017 di bagian bawah.
Anda tidak dapat mengembalikan apa pun dari fungsi yang asinkron. Apa yang dapat Anda kembalikan adalah janji. Saya menjelaskan bagaimana janji bekerja di jQuery dalam jawaban saya untuk pertanyaan-pertanyaan itu:

function testAjax() {
  $.ajax({
    url: "getvalue.php",  
    success: function(data) {
      return data; 
    }
  });
}

Anda dapat menulis fungsi testAjax Anda seperti ini:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

Kemudian Anda bisa mendapatkan janji Anda seperti ini:

var promise = testAjax();

Anda dapat menyimpan janji Anda, Anda dapat meneruskannya, Anda dapat menggunakannya sebagai argumen dalam panggilan fungsi dan Anda dapat mengembalikannya dari fungsi, tetapi ketika Anda akhirnya ingin menggunakan data Anda yang dikembalikan oleh panggilan AJAX, Anda harus melakukannya seperti ini:

promise.success(function (data) {
  alert(data);
});

(Lihat pembaruan di bawah ini untuk sintaksis yang disederhanakan.) Jika data Anda tersedia pada saat ini maka fungsi ini akan segera dipanggil. Jika tidak, maka fungsi ini akan dipanggil segera setelah data tersedia. Inti dari melakukan semua ini adalah bahwa data Anda tidak tersedia segera setelah panggilan ke $.ajax karena bersifat asinkron. Promises adalah abstraksi yang bagus untuk fungsi-fungsi untuk mengatakan: Saya tidak dapat mengembalikan data Anda karena saya belum memilikinya dan saya tidak ingin memblokir dan membuat Anda menunggu, jadi inilah janji sebagai gantinya dan Anda akan dapat menggunakannya nanti, atau hanya memberikannya kepada orang lain dan selesai dengan itu. Lihat ini [DEMO](http://jsfiddle.net/jW68r/). PEMBARUAN (2015)

Saat ini (per Maret, 2015) jQuery Promises tidak kompatibel dengan Promises/A+ specification yang berarti bahwa mereka mungkin tidak bekerja sama dengan baik dengan Promises/A+ conformant implementations. Namun jQuery Promises pada versi 3.x yang akan datang akan kompatibel dengan spesifikasi Promises/A+ (terima kasih kepada Benjamin Gruenbaum yang telah menunjukkannya). Saat ini (per Mei 2015) versi stabil jQuery adalah 1.x dan 2.x.

Apa yang saya jelaskan di atas (pada bulan Maret 2011) adalah cara untuk menggunakan jQuery Deferred Objects untuk melakukan sesuatu secara asinkron yang dalam kode sinkron akan dicapai dengan mengembalikan nilai. Tetapi pemanggilan fungsi sinkron dapat melakukan dua hal - bisa mengembalikan nilai (jika bisa) atau melempar pengecualian (jika tidak bisa mengembalikan nilai). Promises/A+ menangani kedua kasus penggunaan tersebut dengan cara yang cukup kuat seperti penanganan pengecualian dalam kode sinkron. Versi jQuery menangani setara dengan mengembalikan nilai dengan baik tetapi penanganan pengecualian yang kompleks agak bermasalah. Secara khusus, inti dari penanganan pengecualian dalam kode sinkron tidak hanya menyerah dengan pesan yang bagus, tetapi mencoba untuk memperbaiki masalah dan melanjutkan eksekusi, atau mungkin melempar ulang pengecualian yang sama atau berbeda untuk ditangani oleh beberapa bagian lain dari program. Dalam kode sinkron Anda memiliki call stack. Dalam panggilan asinkron Anda tidak memiliki call stack dan penanganan pengecualian lanjutan di dalam janji Anda seperti yang dipersyaratkan oleh spesifikasi Promises / A + benar-benar dapat membantu Anda menulis kode yang akan menangani kesalahan dan pengecualian dengan cara yang berarti bahkan untuk kasus penggunaan yang kompleks. Untuk perbedaan antara jQuery dan implementasi lainnya, dan cara mengonversi janji jQuery menjadi sesuai dengan Promises / A +, lihat Berasal dari jQuery oleh Kris Kowal et al. di perpustakaan Q wiki dan Promises arrive in JavaScript oleh Jake Archibald di HTML5 Rocks.

Bagaimana mengembalikan janji yang sebenarnya

Fungsi dari contoh saya di atas:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

mengembalikan objek jqXHR, yang merupakan jQuery Deferred Object. Untuk membuatnya mengembalikan janji yang nyata, Anda dapat mengubahnya menjadi - menggunakan metode dari Q wiki:

function testAjax() {
  return Q($.ajax({
      url: "getvalue.php"
  }));
}

atau, menggunakan metode dari artikel HTML5 Rocks:

function testAjax() {
  return Promise.resolve($.ajax({
      url: "getvalue.php"
  }));
}

Promise.resolve($.ajax(...)) ini juga yang dijelaskan dalam dokumentasi modul promise dan seharusnya bekerja dengan ES6 Promise.resolve(). Untuk menggunakan ES6 Promise saat ini Anda dapat menggunakan es6-promise module's polyfill() oleh Jake Archibald. Untuk melihat di mana Anda dapat menggunakan ES6 Promises tanpa polyfill, lihat: Can I use: Promises. Untuk info lebih lanjut, lihat:

promise.success(function (data) {
  alert(data);
});

Anda dapat menulis:

promise.success(data => alert(data));

atau menggunakan Promises/A+ API:

promise.then(data => alert(data));

Ingatlah untuk selalu menggunakan penangan penolakan baik dengan:

promise.then(data => alert(data), error => alert(error));

atau dengan:

promise.then(data => alert(data)).catch(error => alert(error));

Lihat jawaban ini untuk melihat mengapa Anda harus selalu menggunakan penangan penolakan dengan janji:

promise.then(data => alert("x is " + data.x));

Belum semua browser mendukung sintaks ini, tetapi ada beberapa kasus tertentu ketika Anda yakin browser apa yang akan digunakan untuk menjalankan kode Anda - misalnya saat menulis Chrome extension, Firefox Add-on, atau aplikasi desktop menggunakan Electron, NW.js, atau AppJS (lihat jawaban ini untuk detailnya). Untuk dukungan fungsi panah, lihat:

  • Ada sintaks yang lebih baru sekarang yang disebut fungsi async dengan kata kunci await baru yang bukan kode ini:
functionReturningPromise()
    .then(data => console.log('Data:', data))
    .catch(error => console.log('Error:', error));

memungkinkan Anda menulis:

try {
    let data = await functionReturningPromise();
    console.log('Data:', data);
} catch (error) {
    console.log('Error:', error);
}

Anda hanya dapat menggunakannya di dalam fungsi yang dibuat dengan kata kunci async. Untuk info lebih lanjut, lihat:

Komentar (9)
Larutan

Satu-satunya cara untuk mengembalikan data dari fungsi tersebut adalah dengan membuat panggilan sinkron, bukan panggilan asinkron, tetapi itu akan membekukan browser saat menunggu respons.

Anda dapat memasukkan fungsi callback yang menangani hasilnya:

function testAjax(handleData) {
  $.ajax({
    url:"getvalue.php",  
    success:function(data) {
      handleData(data); 
    }
  });
}

Panggil seperti ini:

testAjax(function(output){
  // here you use the output
});
// Note: the call won't wait for the result,
// so it will continue with the code here while waiting.
Komentar (7)

anda dapat menambahkan async pilihan untuk palsu dan kembali di luar ajax call.

function testAjax() {
    var result="";
    $.ajax({
      url:"getvalue.php",
      async: false,  
      success:function(data) {
         result = data; 
      }
   });
   return result;
}
Komentar (7)

Idk jika kalian soal itu, tapi saya merekomendasikan cara lain untuk melakukannya, dan bekerja :)

    ServiceUtil = ig.Class.extend({
        base_url : 'someurl',

        sendRequest: function(request)
        {
            var url = this.base_url + request;
            var requestVar = new XMLHttpRequest();
            dataGet = false;

            $.ajax({
                url: url,
                async: false,
                type: "get",
                success: function(data){
                    ServiceUtil.objDataReturned = data;
                }
            });
            return ServiceUtil.objDataReturned;                
        }
    })

Jadi ide utama di sini adalah bahwa, dengan menambahkan async: false, maka anda membuat semuanya menunggu sampai data yang diperoleh. Kemudian anda menetapkan ke sebuah variabel statis kelas, dan segala sesuatu yang ajaib bekerja :)

Komentar (1)

Lihat contoh dokumen jquery: http://api.jquery.com/jQuery.ajax/ (sekitar 2/3 halaman)

Anda mungkin mencari kode berikut:

    $.ajax({
     url: 'ajax/test.html',
     success: function(data) {
     $('.result').html(data);
     alert('Load was performed.');
   }
});

Halaman yang sama...lebih rendah.

Komentar (0)