jquery - trả về giá trị bằng cách sử dụng kết quả ajax khi thành công


95

Tôi gặp sự cố nhỏ với hàm jquery $ .ajax ().

Tôi có một biểu mẫu trong đó mỗi lần nhấp vào nút radio hoặc lựa chọn từ menu thả xuống sẽ tạo ra một biến phiên với giá trị đã chọn.

Bây giờ - tôi có một trong các menu thả xuống có 4 tùy chọn - tùy chọn đầu tiên (với nhãn Không có) có giá trị = "" người khác có id của họ.

Điều tôi muốn xảy ra là tùy chọn Không có (với giá trị trống) để xóa phiên và khác để tạo một phiên, nhưng chỉ khi phiên có tên lựa chọn cụ thể này chưa tồn tại - vì tất cả các tùy chọn khác đều có cùng số tiền được gán cho nó - nó chỉ cho biết cái nào đã được chọn.

Tôi không chắc điều đó có hợp lý không - nhưng hãy xem mã - có lẽ điều này sẽ làm cho nó rõ ràng hơn:

$("#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();
});

vì vậy - trước hết khi trình đơn #add_ons select kích hoạt "thay đổi", chúng tôi nhận được một số giá trị từ một vài phần tử để tính toán.

chúng tôi lấy thuộc tính nhãn của tùy chọn từ lựa chọn của chúng tôi để lưu trữ giá trị sẽ được thêm vào tổng số, tên của lựa chọn để tạo phiên với tên và giá trị này để sau này kiểm tra xem cái nào đã được chọn.

bây giờ - chúng tôi kiểm tra xem val == "" (sẽ cho biết rằng Không có tùy chọn nào đã được chọn) và chúng tôi trừ số tiền khỏi tổng số cũng như xóa phiên có tên của lựa chọn.

Sau đây là nơi vấn đề bắt đầu - câu lệnh else.

Khác - chúng tôi muốn kiểm tra xem hàm isSession () với tên của bộ chọn của chúng tôi trả về 0 hay 1 - nếu nó trả về 0 thì chúng tôi thêm vào tổng giá trị được lưu trữ trong thuộc tính nhãn, nhưng nếu nó trả về 1 - điều đó sẽ gợi ý phiên đó đã tồn tại - sau đó chúng tôi chỉ thay đổi giá trị của phiên này bằng cách tạo lại nó - nhưng số tiền không được thêm vào nó.

Bây giờ hàm isSession trông như thế này:

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');
        }
    });
}

Bây giờ - vấn đề là - tôi không biết liệu việc sử dụng "return" có trả về kết quả từ hàm hay không - vì nó dường như không hoạt động - tuy nhiên, nếu tôi đặt "data" trong phần thành công: cảnh báo - nó dường như trả về giá trị phù hợp.

Có ai biết cách trả về giá trị từ hàm và sau đó so sánh nó trong câu lệnh tiếp theo không?


Cảm ơn các bạn - Tôi đã thử theo cách sau:

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');
        }
    });
}

thì hàm updateResult ():

function updateResult (data) {result = data; }

kết quả - là biến toàn cục - sau đó tôi đang cố đọc:

$("#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();
    });

nhưng vì lý do nào đó - nó không hoạt động - bất kỳ ý tưởng nào?



Nó có thể giúp giải quyết vấn đề này: stackoverflow.com/questions/14220321/...
mirzaei.sajad

Câu trả lời:


113

Rắc rối là bạn không thể trả về một giá trị từ một lệnh gọi không đồng bộ, chẳng hạn như một yêu cầu AJAX và mong đợi nó hoạt động.

Lý do là mã chờ phản hồi đã được thực thi vào thời điểm nhận được phản hồi.

Giải pháp cho vấn đề này là chạy mã cần thiết bên trong lệnh success:gọi lại. Bằng cách đó, nó đang truy cập dataduy nhất khi nó có sẵn.

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');
        }
    });
}

Một khả năng khác (hiệu quả tương tự) là gọi một hàm bên trong lệnh success:gọi lại của bạn để chuyển dữ liệu khi nó có sẵn.

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
}

11
Bạn CÓ THỂ trả về một giá trị từ một yêu cầu AJAX, nhưng đó chỉ khi bạn đặt nó thành không đồng bộ (đặt tùy chọn async: false). Trong một số trường hợp, không bắt buộc phải có một cuộc gọi không đồng bộ. Thông tin thêm về jquery.ajax () doc api.jquery.com/jQuery.ajax , không phải làAs of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;
Adrien Be

48
"Không đồng bộ" tất nhiên cũng có thể được gọi là "đồng bộ";)
Charles Wood

trong cả hai phương pháp bạn đã đề xuất; I E. chạy hàm thành công, sau đó bạn phải viết nhiều ajax cho các tình huống khác nhau. điều này sẽ không giúp ích gì trong việc tạo một công cụ, trình bao bọc ajax toàn cầu.
wpcoder

Có vẻ như async: false hiện không được dùng nữa và tất cả các quá trình xử lý cần được thực hiện trong các hàm gọi lại.
Puneet Lamba

31

Có nhiều cách để nhận phản hồi jQuery AJAX. Tôi đang chia sẻ với bạn hai cách tiếp cận phổ biến:

Đầu tiên:

sử dụng async = false và bên trong hàm trả về ajax-object và sau đó nhận được phản hồi 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);
});

Thứ hai:

sử dụng phương thức $ .extend và tạo một hàm mới như ajax

/**
 * 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);

bạn có thể làm cho nó lớn như bạn muốn ...


Ý tưởng tốt đẹp nhưng ajaxObj['responseText']không tồn tại khi bạn xác địnhvar ajaxResponse
mu3

Hoàn hảo!! giải pháp đầu tiên của bạn đã cứu tôi
Kallel Omar

phương pháp thứ hai là 100% A OK! ;)
Schalk Keun

7
Kể từ jQuery 1.8, việc sử dụng async: false không được chấp nhận!
gatteo

10

Tôi đã thấy các câu trả lời ở đây và mặc dù hữu ích, chúng không chính xác là những gì tôi muốn vì tôi phải thay đổi rất nhiều mã của mình.

Điều gì đã làm cho tôi, đã làm một cái gì đó như thế này:

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;
}

Hy vọng sẽ giúp ai đó

anakin


4
Bạn thực sự chỉ cần tắt async
Weijing Jay Lin

4

Mặc dù tất cả các cách tiếp cận liên quan đến việc sử dụng async: falseđều không tốt vì nó không còn được dùng nữa và bị kẹt trang cho đến khi yêu cầu quay trở lại. Vì vậy, đây là 2 cách để làm điều đó:

Thứ nhất: Trả lại toàn bộ phản hồi ajax trong một hàm và sau đó sử dụng donechức năng để ghi lại phản hồi khi yêu cầu được hoàn thành. (KHUYẾN CÁO, CÁCH TỐT NHẤT)

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

HÃY GỌI NGƯỜI TRÊN NHƯ VẬY:

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

ĐỂ CÓ NHIỀU CUỘC GỌI AJAX, HÃY SỬ DỤNG $.when:

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

Thứ 2: Lưu trữ phản hồi trong cookie và sau đó bên ngoài lệnh gọi ajax lấy giá trị cookie đó. (KHÔNG KHUYẾN CÁO)

        $.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);

LƯU Ý: Trong jquery cookiesthư viện exmple ở trên được sử dụng, nó khá nhẹ và hoạt động rất linh hoạt. Đây là link https://github.com/js-cookie/js-cookie


3

Thêm vào async: falsedanh sách thuộc tính của bạn. Điều này buộc luồng javascript phải đợi cho đến khi giá trị trả về được truy xuất trước khi tiếp tục. Rõ ràng, bạn sẽ không muốn làm điều này trong mọi trường hợp, nhưng nếu cần một giá trị trước khi tiếp tục, điều này sẽ làm được.


3
Bạn không bao giờ nên đặt async: false. Điều này chặn mọi nội dung trên trang trong suốt thời gian truy xuất. Bạn biết chữ A trong AJAX là viết tắt của: Không đồng bộ. Câu trả lời thích hợp sẽ là OP cần sử dụng lệnh success()gọi lại đúng cách.
nietonfir

2
Tôi thừa nhận một thực tế là mọi thứ đều phải chờ đợi. Trong một số trường hợp nhất định, hàm gọi có thể cần giá trị trả về, chẳng hạn như thêm bản ghi mới và cần trả về id bản ghi. Một khi bạn biết các quy tắc, bạn biết khi nào chúng có thể bị phá vỡ. Không bao giờ nói không bao giờ. Đây là một người khác đồng tình. ( stackoverflow.com/questions/3880361/… )
Hoodlum

1
@CharlesWood Chỉ dành cho những người không thể hiểu được bản chất không đồng bộ của ajax.
nietonfir

1
@nietonfir: nếu bạn không bao giờ nên sử dụng async: falsetại sao jQuery lại triển khai tùy chọn này? nếu tôi không tải một lượng lớn dữ liệu vào trang và chỉ xử lý một sự kiện của người dùng, nó sẽ chặn mọi thứ khác trong một khoảng thời gian ngắn cho người dùng cụ thể đó. không có gì sai và không có gì xấu về nó. (nếu sử dụng đúng cách, nó sẽ không chặn bất cứ điều gì bởi vì trong thời điểm đặc biệt hành động không khác cho rằng người dùng cụ thể sẽ xảy ra)
low_rents

1
@northkildonan Không, không ổn đâu. Yêu cầu AJAX đồng bộ không hợp lệ. Nó chặn chuỗi javascript hoàn chỉnh bằng thứ gì đó mà bạn không thể kiểm soát. Bạn không có quyền kiểm soát lượng thời gian có thể mất để xử lý yêu cầu: kết nối có thể không đáng tin cậy, máy chủ có thể mất nhiều thời gian hơn dự kiến, v.v. Lý do duy nhất trong jQuery là bạn có thể cần lưu dữ liệu khi dỡ trang (nơi duy nhất không thực sự quan trọng nếu mất nhiều thời gian hơn, vì người dùng đã bày tỏ mong muốn rời khỏi trang). Chỉ cần nhìn vào các bài kiểm tra đơn vị jQuery ...
nietonfir

3

Điều này khá cũ và xấu xí, đừng làm điều này. Bạn nên sử dụng callbacks: https://stackoverflow.com/a/5316755/591257
Gặp vấn đề tương tự, đã giải quyết nó theo cách này, sử dụng global var. Không chắc nó có phải là tốt nhất hay không nhưng chắc chắn hoạt động. Nếu xảy ra lỗi, bạn nhận được một chuỗi trống (myVar = ''), vì vậy bạn có thể xử lý điều đó nếu cần.

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;
}

3
bạn cũng cần thêm async: falsevào đây, bởi vì ở chế độ không đồng bộ, nó không được đảm bảo rằng những gì datađược lưu vào myVartrước đó myVarsẽ được trả về.
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);
}

nó có thể hữu ích, tạo một hàm gọi ajax chung và đính kèm một hàm gọi khi thành công lệnh gọi ajax, hãy xem ví dụ


1

Với sự trợ giúp từ đây

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;
}

Hy vọng điều này sẽ giúp ai đó ở đâu đó một chút.


Việc sử dụng async: false,là thời tiền sử và bị phản đối kể từ jQuery v1.8, Nó có thể sẽ giúp không ai
Alon Eitan

-2

Xin chào, hãy thử async: false trong cuộc gọi ajax của bạn ..

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.