2012-02-20 67 views
6

Tôi tương đối mới với JavaScript và tôi nghĩ mình đã biết cách hoạt động của hàm gọi lại nhưng sau một vài giờ tìm kiếm trên web tôi vẫn không hiểu tại sao mã của tôi không hoạt động.Đặt biến cục bộ trong hàm gọi lại JavaScript

Tôi đang thực hiện yêu cầu AJAX trả về một mảng chuỗi. Tôi đang cố gắng để thiết lập mảng này đến một biến địa phương, nhưng nó dường như mất giá trị của nó ngay sau khi chức năng gọi lại được thực thi.

var array; 

    $.ajax({ 
     type: 'GET', 
     url: 'include/load_array.php', 
     dataType: 'json', 
     success: function(data){ 
      array = data; 
     }, 
     error: function(jqXHR, textStatus, errorThrown){ 
      alert("Error loading the data"); 
     } 
    }); 

    console.debug(array); 

Trong bảng điều khiển, array xuất hiện dưới dạng không xác định. Bất cứ ai có thể giải thích cho tôi lý do tại sao điều này không được thiết lập và làm thế nào nó có thể thiết lập một biến địa phương trong một chức năng gọi lại.

Trả lời

7

Vấn đề ở đây là console.log thực hiện đồng bộ trong khi lệnh ajax thực hiện không đồng bộ. Do đó, nó chạy trước khi hoàn thành gọi lại để nó vẫn thấy arrayundefinedsuccess chưa chạy. Để thực hiện công việc này, bạn cần phải trì hoãn cuộc gọi console.log cho đến khi sau khi hoàn thành success.

$(document).ready(function() { 
    var array; 

    var runLog = function() { 
     console.log(array); 
    }; 

    $.ajax({ 
     type: 'GET', 
     url: 'include/load_array.php', 
     dataType: 'json', 
     success: function(data){ 
     array = data; 
     runlog(); 
    }}); 
}); 
+0

Tôi nghĩ bạn đang bối rối bởi định dạng của mã. 'Console.debug' là trực tiếp sau' ajax'. –

+0

Tôi tin rằng phạm vi là chính xác, nó chỉ là định dạng được tắt cho hai dòng đầu tiên không trống (họ nên được chuyển sang trái 1). – GoldenNewby

+0

@JamesMontagne bạn chính xác là đúng. Các định dạng thực sự đã ném tôi đi. Đã cập nhật câu trả lời. – JaredPar

2

Dấu đầu tiên trong ajax là không đồng bộ, có nghĩa là khi bạn đang gỡ lỗi mảng, kết quả vẫn chưa được gửi. Mảng là không xác định tại thời điểm hiển thị giá trị của nó. Bạn cần phải làm console.debug bên dưới mảng = dữ liệu.

+0

Ah ha, có vẻ như quá rõ ràng bây giờ! Có một thay thế cho AJAX mà bạn muốn giới thiệu để đảm bảo rằng chương trình chờ phản hồi trước khi nó tiếp tục thực hiện? – Alex

+0

Bạn có thể thực hiện các cuộc gọi http đồng bộ bằng javascript, nhưng không có lý do nào bạn nên làm. Chỉ cần bắt đầu làm việc với kết quả trong phạm vi bên phải trong lần tiếp theo. – GoldenNewby

+2

Đó là SJAX. Đồng bộ, tức là việc thực hiện sẽ bị chặn cho đến khi kết quả được truy lục. Trong json yêu cầu của bạn, nếu bạn giới thiệu async: false, thì quá trình truy xuất sẽ đồng bộ - theo những từ đơn giản, mã trước của bạn sẽ hoạt động. Nhưng sau đó một lần nữa, đây là thực hành xấu. Đặt mã gỡ rối của bạn bên trong một cuộc gọi lại như được chỉ ra bởi GoldenNewby là cách để đi. –

1

Chức năng success không thực thi ngay lập tức, nhưng chỉ sau khi phản hồi HTTP đến. Do đó, array vẫn là undefined vào thời điểm này. Nếu bạn muốn thực hiện các thao tác trên dữ liệu phản hồi HTTP, hãy thực hiện nó từ bên trong hàm success, hoặc cách khác, xác định hoạt động đó bên trong một hàm và sau đó gọi hàm đó từ bên trong cuộc gọi lại success.

0

AJAX không đồng bộ. Bạn đang đặt biến số array, nhưng không phải cho đến sau đó debug thực thi. Thực hiện cuộc gọi AJAX sẽ gửi yêu cầu nhưng sau đó tiếp tục trong mã. Tại một số điểm sau này, yêu cầu trả về và các hàm success hoặc error của bạn được thực hiện.

1

Thử gọi một chức năng để thiết lập biến này sau success của bạn:

var array; 

var goodToProceed = function(myArr) { 
    console.debug(myArr); 
}; 

$.ajax({ 
type: 'GET', 
url: 'include/load_array.php', 
dataType: 'json', 
success: function(data){ 
    goodToProceed(data); 
}, 
error: function(jqXHR, textStatus, errorThrown){ 
    alert("Error loading the data"); 
} 
}); 
+2

Tại sao phải thực hiện một chức năng ẩn danh gọi goodToProceed thay vì chỉ có nó được gọi trực tiếp khi thành công? – GoldenNewby

+0

Có GoldenNewby, điểm tốt. Tôi làm điều đó thường xuyên nhưng thực sự, không cần phải làm điều đó. – adis

+0

@adis, đôi khi là tốt để làm điều đó, để gỡ rối mã, tuy nhiên, bạn không cần một hàm ẩn danh trong trường hợp đó. chỉ cần xác định 'thành công: goodToProceed,' – stivlo

Các vấn đề liên quan