jquery - başarı durumunda ajax sonucunu kullanarak değer döndürür


97

Jquery $ .ajax () işleviyle ilgili küçük bir sorunum var.

Radyo düğmesine her tıklamanın veya açılır menüden yapılan seçimin seçilen değere sahip bir oturum değişkeni oluşturduğu bir formum var.

Şimdi - 4 seçeneğe sahip açılır menülerden birine sahibim - ilki (Yok etiketli) bir değere sahip = "" diğerinin kimlikleri var.

Olmasını istediğim şey, Oturumu kaldırmak ve diğerini oluşturmak için Yok seçeneğine (boş değerle), ancak yalnızca bu belirli adla oturum mevcut değilse - diğer tüm seçeneklere aynı miktar atanmış olduğundan - sadece hangisinin seçildiğini gösteriyor.

Bunun mantıklı olup olmadığından emin değilim - ama koda bir göz atın - belki bu daha açık hale getirecektir:

$("#add_ons select").change(function() {
        // get current price of the addons
        var order_price_addon = $(".order_price_addon").text();
        // get price of the clicked radio button from the rel attribute
        var add = $(this).children('option').attr('label');
        var name = $(this).attr('name');
        var val = $(this).val();


        if(val == "") {
            var price = parseInt(order_price_addon) - parseInt(add);
            removeSession(name);
        } else {
            if(isSession(name) == 0) {
                var price = parseInt(order_price_addon) + parseInt(add);
            }   
            setSession(name, val);              
        }

        $(".order_price_addon").html(price);    
        setSession('order_price_addon', price);         
        updateTotal();
});

so - her şeyden önce #add_ons seçme menüsü "değiştir" i tetiklediğinde, hesaplamalar için birkaç öğeden bazı değerler alırız.

Toplama eklenecek değeri depolayan seçeneğimizin label niteliğini, bu adla oluşturmak için select oturumunun adını ve daha sonra hangisinin seçildiğini kontrol etmek için değeri alırız.

şimdi - val == "" (Hiçbiri seçeneğinin seçildiğini gösterir) kontrol ediyoruz ve miktarı toplamdan düşüyoruz ve ayrıca select adıyla oturumu kaldırıyoruz.

Bundan sonra sorunun başladığı yer - else ifadesi.

Aksi takdirde - seçicimizin adıyla isSession () işlevinin 0 mı yoksa 1 mi döndürdüğünü kontrol etmek istiyoruz - 0 döndürürse, etiket özelliğinde depolanan toplam değeri ekleriz, ancak 1 döndürürse - bu önerecektir bu oturum zaten var - o zaman bu oturumun değerini yalnızca yeniden oluşturarak değiştiririz - ancak miktar buna eklenmez.

Şimdi isSession işlevi şuna benzer:

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

Şimdi - sorun şu ki - "return" kullanmanın işlevden sonucu döndürüp döndürmeyeceğini bilmiyorum - işe yaramıyor gibi görünüyor - ancak, başarıdaki "verileri" bölüme koyarsam: uyarı - doğru değeri döndürüyor gibi görünüyor.

İşlevden değerin nasıl döndürüleceğini bilen ve sonraki ifadede onu karşılaştıran var mı?


Teşekkürler çocuklar - Bunu şu şekilde denedim:

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            updateResult(data);
        },
        error: function() {
            alert('Error occured');
        }
    });
}

daha sonra updateResult () işlevi:

function updateResult (veri) {sonuç = veri; }

sonuç - daha sonra okumaya çalıştığım küresel değişkendir:

$("#add_ons select").change(function() {
        // get current price of the addons
        var order_price_addon = $(".order_price_addon").text();
        // get price of the clicked radio button from the rel attribute
        var add = $(this).children('option').attr('label');
        var name = $(this).attr('name');
        var val = $(this).val();


        if(val == "") {
            var price = parseInt(order_price_addon) - parseInt(add);
            removeSession(name);
        } else {
            isSession(name);
            if(result == 0) {
                var price = parseInt(order_price_addon) + parseInt(add);
            }   
            setSession(name, val);              
        }

        $(".order_price_addon").html(price);    
        setSession('order_price_addon', price);         
        updateTotal();
    });

ama nedense - işe yaramıyor - herhangi bir fikir?



Bu sorunu çözmeye yardımcı olabilir: stackoverflow.com/questions/14220321/…
mirzaei.sajad

Yanıtlar:


115

Sorun şu ki, AJAX isteği gibi eşzamansız bir çağrıdan bir değer döndüremiyor ve çalışmasını bekleyemiyorsunuz.

Bunun nedeni, yanıtı bekleyen kodun yanıt alındığında zaten yürütülmüş olmasıdır.

Bu sorunun çözümü , geri arama içinde gerekli kodu çalıştırmaktır success:. Bu şekilde, datayalnızca mevcut olduğunda erişilir .

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            // Run the code here that needs
            //    to access the data returned
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

Diğer bir olasılık (aslında aynı şey), geri aramanızın içinde success:, mevcut olduğunda verileri ileten bir işlevi çağırmaktır .

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
                // Call this function on success
            someFunction( data );
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

function someFunction( data ) {
    // Do something with your data
}

12
Bir AJAX isteğinden bir değer döndürebilirsiniz, ancak bu yalnızca eşzamansız yaparsanız (seçeneği ayarlayın async: false). Bazı durumlarda, eşzamansız bir arama yapılması gerekli değildir. Jquery.ajax () doc api.jquery.com/jQuery.ajax hakkında daha fazla bilgi , o değilAs of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;
Adrien Be

50
"Eşzamansız" elbette "eşzamanlı" olarak da anılabilir;)
Charles Wood

önerdiğiniz her iki yöntemde de; yani. işlevi başarıyla çalıştırırsanız, farklı senaryolar için birden fazla ajax yazmanız gerekir. bu küresel bir ajax sarmalayıcı, motor oluşturmaya yardımcı olmaz.
wpcoder

Görünüşe göre async: false artık kullanımdan kaldırıldı ve tüm işlemlerin geri arama işlevlerinde yapılması gerekiyor.
Puneet Lamba

33

JQuery AJAX yanıtı almanın birçok yolu vardır. Sizlerle iki ortak yaklaşımı paylaşıyorum:

İlk:

async = false kullanın ve işlev içinde dön ajax-object ve sonra yanıt al ajax-object.responseText

/**
 * jQuery ajax method with async = false, to return response
 * @param  {mix}  selector - your selector
 * @return {mix}           - your ajax response/error
 */
function isSession(selector) {
    return $.ajax({
        type: "POST",
        url: '/order.html',
        data: {
            issession: 1,
            selector: selector
        },
        dataType: "html",
        async: !1,
        error: function() {
            alert("Error occured")
        }
    });
}
// global param
var selector = !0;
// get return ajax object
var ajaxObj = isSession(selector);
// store ajax response in var
var ajaxResponse = ajaxObj.responseText;
// check ajax response
console.log(ajaxResponse);
// your ajax callback function for success
ajaxObj.success(function(response) {
    alert(response);
});

İkinci:

$ .extend yöntemini kullanın ve ajax gibi yeni bir işlev oluşturun

/**
 * xResponse function
 *
 * xResponse method is made to return jQuery ajax response
 * 
 * @param  {string} url   [your url or file]
 * @param  {object} your ajax param
 * @return {mix}       [ajax response]
 */
$.extend({
    xResponse: function(url, data) {
        // local var
        var theResponse = null;
        // jQuery ajax
        $.ajax({
            url: url,
            type: 'POST',
            data: data,
            dataType: "html",
            async: false,
            success: function(respText) {
                theResponse = respText;
            }
        });
        // Return the response text
        return theResponse;
    }
});

// set ajax response in var
var xData = $.xResponse('temp.html', {issession: 1,selector: true});

// see response in console
console.log(xData);

istediğiniz kadar büyütebilirsiniz ...


Güzel fikir ama ajaxObj['responseText']tanımlarken yokvar ajaxResponse
mu3

Mükemmel!! İlk çözümün beni kurtardı
Kallel Omar

ikinci yöntem% 100 A OK! ;)
Schalk Keun

7
JQuery 1.8'den itibaren, async: false kullanımdan kaldırılmıştır!
gatteo

10

Cevapları burada gördüm ve yardımcı olsalar da, kodumun çoğunu değiştirmek zorunda olduğum için tam olarak istediğim şey değildi.

Benim için işe yarayan şey şöyle bir şey yapmaktı:

function isSession(selector) {
    //line added for the var that will have the result
    var result = false;
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        //line added to get ajax response in sync
        async: false,
        success: function(data) {
            //line added to save ajax response in var result
            result = data;
        },
        error: function() {
            alert('Error occured');
        }
    });
    //line added to return ajax response
    return result;
}

Umut birine yardım eder

Anakin


5

6

Kullanımıyla ilgili tüm yaklaşımlar, kullanımdan async: falsekaldırılması nedeniyle iyi olmasa da, istek geri gelene kadar sayfayı sıkıştı. İşte bunu yapmanın 2 yolu:

1: Tüm ajax yanıtını bir işlevde döndürür ve ardından doneistek tamamlandığında yanıtı yakalamak için işlevi kullanır. (ÖNERİLEN, EN İYİ YOL)

function getAjax(url, data){
    return $.ajax({
        type: 'POST',
        url : url,              
        data: data,
        dataType: 'JSON',
        //async: true,  //NOT NEEDED
        success: function(response) {
            //Data = response;
        }
    });
 }

YUKARIDAKİ GİBİ ARAYIN:

getAjax(youUrl, yourData).done(function(response){
    console.log(response);
});

ÇOKLU AJAX ARAMALARI İÇİN ŞUNLARI KULLANIN $.when:

$.when( getAjax(youUrl, yourData), getAjax2(yourUrl2, yourData2) ).done(function(response){
    console.log(response);
});

2: Yanıtı bir çerezde saklayın ve ardından ajax çağrısının dışında bu çerez değerini alın. (ÖNERİLMEZ)

        $.ajax({
            type: 'POST',
            url : url,              
            data: data,
            //async: false,    // No need to use this
            success: function(response) {
                Cookies.set(name, response);
            }
        });

        // Outside of the ajax call
        var response = Cookies.get(name);

NOT: Yukarıdaki örnekte jquery cookieskitaplık kullanılmıştır, oldukça hafiftir ve çabuk çalışır. İşte bağlantı https://github.com/js-cookie/js-cookie


3

async: falseÖznitelik listenize ekleyin . Bu, javascript iş parçacığını, devam etmeden önce dönüş değeri alınana kadar beklemeye zorlar. Açıkçası, bunu her durumda yapmak istemezsiniz, ancak devam etmeden önce bir değere ihtiyaç duyulursa, bu işe yarar.


4
Asla ayarlamamalısın async: false. Bu, alma süresi boyunca sayfadaki her şeyi engeller. AJAX'taki A'nın ne anlama geldiğini biliyorsunuz: Asenkron. Doğru cevap, OP'nin success()geri aramayı doğru şekilde kullanması gerektiğidir .
nietonfir

2
Her şeyin beklemesi gerektiği gerçeğini kabul ettim. Belirli koşullar altında, çağıran işlev, yeni bir kayıt eklemek ve bir kayıt kimliğinin döndürülmesini gerektirmek gibi döndürülen bir değere ihtiyaç duyabilir. Kuralları öğrendikten sonra, ne zaman çiğnenebileceklerini bilirsiniz. Asla asla Deme. İşte aynı fikirde olan başka biri. ( stackoverflow.com/questions/3880361/… )
Hoodlum

1
@CharlesWood Yalnızca ajax'ın eşzamansız doğasını kavrayamayanlar için.
nietonfir

1
@nietonfir: Hiç kullanmayacaksanız async: falsejQuery neden bu seçeneği uygulasın ? Sayfaya büyük miktarda veri yüklemiyorsam ve yalnızca bir kullanıcı olayını yönetiyorsam, diğer her şeyi o belirli kullanıcı için kısa sürede engellemekte sorun yok. bunda yanlış ve kötü bir şey yok. (doğru kullanılırsa hiçbir şeyi engellemez çünkü o belirli zamanda o belirli kullanıcı için başka bir işlem gerçekleşmez)
low_rents

1
@northkildonan Hayır, tamam değil. Senkronizasyon AJAX isteği hatalı. Tam javascript iş parçacığını kontrol edemeyeceğiniz bir şeyle engeller. İsteği işlemek için gerekebilecek süre üzerinde kontrolünüz yok: bağlantı güvenilmez olabilir, sunucu beklenenden daha uzun sürebilir, vb. JQuery'de olmasının tek nedeni , verileri kaydetmeniz gerekebilmesidir. sayfa boşaltma (kullanıcı sayfadan ayrılma isteğini zaten ifade ettiği için daha uzun sürmesinin gerçekten önemli olmadığı tek yer). Sadece jQuery birim testlerine bakın…
nietonfir

3

Bu oldukça eski ve çirkin, bunu yapma. Geri aramaları kullanmalısınız: https://stackoverflow.com/a/5316755/591257
Aynı sorunu yaşadım, bu şekilde, global bir var. En iyisi olup olmadığından emin değilim ama kesinlikle işe yarıyor. Hata durumunda boş bir dize (myVar = '') alırsınız, böylece bunu gerektiği gibi halledebilirsiniz.

var myVar = '';
function isSession(selector) {
  $.ajax({
    'type': 'POST',
    'url': '/order.html',
    'data': {
      'issession': 1,
      'selector': selector
    },
    'dataType': 'html',
    'success': function(data) {
      myVar = data;
    },
    'error': function() {
      alert('Error occured');
    }
  });
  return myVar;
}

4
Ayrıca async: falseburaya eklemeniz gerekir , çünkü eşzamansız modda geri döndürülmeden önce datakaydedileceği garanti edilmez . myVarmyVar
low_rents

2
// Common ajax caller
function AjaxCall(url,successfunction){
  var targetUrl=url;
  $.ajax({
    'url': targetUrl,
    'type': 'GET',
    'dataType': 'json',
    'success': successfunction,
    'error': function() {
      alert("error");
    }
  });
}

// Calling Ajax
$(document).ready(function() {
  AjaxCall("productData.txt",ajaxSuccessFunction);
});

// Function details of success function
function ajaxSuccessFunction(d){
  alert(d.Pioneer.Product[0].category);
}

yardımcı olabilir, ortak bir ajax çağrısı işlevi yaratabilir ve başarılı olduğunda ajax çağrısı başlatan bir işlev ekleyebilir, örneğe bakın


1

Buradan yardım alarak

function get_result(some_value) {
   var ret_val = {};
   $.ajax({
       url: '/some/url/to/fetch/from',
       type: 'GET',
       data: {'some_key': some_value},
       async: false,
       dataType: 'json'
   }).done(function (response) {
       ret_val = response;
   }).fail(function (jqXHR, textStatus, errorThrown) {
           ret_val = null;
       });
   return ret_val;
}

Umarım bu, birine biraz yardımcı olur.


Kullanımı async: false,Muhtemelen kimse yardımcı olacaktır, tarih öncesi ve jQuery v1.8 beri kullanımdan kaldırıldı
Alon Eitan

-2

Merhaba async deneyin : ajax çağrınızda yanlış ..

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.