Pertanyaan jQuery ajax success anonymous function scope


Bagaimana cara memperbarui variabel returnHtml dari dalam fungsi sukses anonim?

function getPrice(productId, storeId) {
    var returnHtml = '';

    jQuery.ajax({
        url: "/includes/unit.jsp?" + params,
        cache: false,
        dataType: "html",
        success: function(html){
            returnHtml = html;
        }
    });

    return returnHtml;
}

37
2017-09-22 01:21


asal


Jawaban:


Itu pendekatan yang salah. A pertama di AJAX Asynchronous. Fungsi itu kembali sebelum panggilan AJAX kembali (atau setidaknya bisa). Jadi ini bukan masalah ruang lingkup. Ini masalah pemesanan. Hanya ada dua opsi:

  1. Buat panggilan AJAX sinkron (tidak direkomendasikan) dengan async: false pilihan; atau
  2. Ubah cara berpikir Anda. Alih-alih mengembalikan HTML dari fungsi yang Anda butuhkan untuk melewati panggilan balik untuk dipanggil ketika panggilan AJAX berhasil.

Sebagai contoh dari (2):

function findPrice(productId, storeId, callback) {
    jQuery.ajax({
        url: "/includes/unit.jsp?" + params,
        cache: false,
        dataType: "html",
        success: function(html) {
            callback(productId, storeId, html);
        }
    });
}

function receivePrice(productId, storeId, html) {
    alert("Product " + productId + " for storeId " + storeId + " received HTML " + html);
}

findPrice(23, 334, receive_price);

58
2017-09-22 01:27



Jawaban singkat, Anda tidak bisa, A pertama di AJAX adalah singkatan Asynchronous, yang artinya permintaan masih berjalan ketika Anda sampai ke pernyataan kembali.

Kamu bisa melakukannya dengan permintaan sinkron (non-async), tetapi umumnya a Sesuatu yang buruk

Sesuatu seperti yang berikut ini harus mengembalikan data.

function getPrice(productId, storeId) {
  var returnHtml = '';

  jQuery.ajax({
    url: "/includes/unit.jsp?" + params,
    async: false,
    cache: false,
    dataType: "html",
    success: function(html){
      returnHtml = html;
    }
  });

  return returnHtml;
}

TAPI

Kecuali Anda benar-benar benar-benar harus dapat menggunakan nilai kembali dari tes langsung, Anda akan banyak lebih baik menyampaikan callback ke dalam tes. Sesuatu seperti

function getPrice(productId, storeId, callback) {
  jQuery.ajax({
    url: "/includes/unit.jsp?" + params,
    async: true,
    cache: false,
    dataType: "html",
    success: function(html){
      callback(html);
    }
  });
}

//the you call it like
getPrice(x,y, function(html) {
    // do something with the html
}

Edit Sheesh, kalian lebih cepat mengatakan apa yang kukatakan :-)


14
2017-09-22 01:30



Fungsi anonim Anda di sana tidak memiliki akses ke returnHtml variabel dalam ruang lingkupnya, sehingga kode di sana benar-benar berfungsi seperti yang Anda harapkan. Di mana Anda mungkin salah dalam pernyataan Anda kembali.

Ingat bahwa SEBUAH di AJAX berdiri untuk asynchronous, yang berarti itu tidak terjadi pada saat yang bersamaan. Untuk alasan itu, garisnya returnHtml = html sebenarnya terjadi setelah kamu panggil return returnHtml;, jadi returnHtml masih merupakan string kosong.

Sulit untuk mengatakan apa yang harus Anda lakukan untuk mendapatkan ini bekerja yang Anda inginkan tanpa melihat sisa kode Anda, tetapi apa yang dapat Anda lakukan adalah menambahkan panggilan balik lain ke fungsi:

function getPrice(productId, storeId, callback) {
    jQuery.ajax({
        url: "/includes/unit.jsp?" + params,
        cache: false,
        dataType: "html",
        success: callback
    });
}

getPrice(5, 1, function(html) {
    alert(html);
});

12
2017-09-22 01:29