2012-07-02 23 views
7

Được rồi ... lúc 2 giờ sáng, đây là nơi tôi vẽ đường kẻ. Trợ giúp ... trước khi máy tính xách tay của tôi kết thúc đi ra ngoài cửa sổ. :)Đợi AJAX trước khi tiếp tục thông qua chức năng riêng biệt

Tôi đã thử sử dụng setTimer, gọi lại và mọi thứ khác mà tôi có thể nghĩ đến (cùng với một vài gợi ý Stackoverflow khác). Tôi đã loại bỏ tất cả mọi thứ vì vậy tôi chỉ để lại mã cơ sở.

Điều tôi đang làm là gọi parseRow() và trước khi lưu bản ghi ở cuối, tôi cần lấy Danh mục liên quan (qua AJAX); tuy nhiên, nó thổi ngay qua nó để danh mục luôn "không xác định".

function parseRow(row){ 
    var rowArray  = row.trim().split(","); 
    var date   = rowArray[0]; 
    var checknum  = rowArray[1]; 
    var payee  = rowArray[2]; 
    var memo   = rowArray[3]; 
    var amount  = rowArray[4]; 

    //ERROR: blows right past this one and sets the category variable BEFORE ajax returns 
    var category = autoSelectCategory(payee); 

    saveRecord(date, checkNum, payee, memo, category, payment, deposit); 
} 

function autoSelectCategory(payee) { 
    var data; 
    $.ajax({ 
     async: false, 
     url: "autoselectcategory", 
     dataType: "json", 
     data: { 
      string: payee 
     }, 
     success: function (returnedData) { 
      data = returnedData; 
     } 
    }); 
    return data; 
} 
+0

EDIT: Tôi đã thêm gợi ý kỳ quái của anh ấy để trả lời câu trả lời của penartur vì tôi là một moron và không trả lại dữ liệu đúng - đó là những gì tôi nhận được để thức quá muộn. Trên thực tế hiện các trick ngay bây giờ. Tuy nhiên, tôi sẽ thực hiện cuộc gọi lại. – glassfish

Trả lời

12

AJAX là viết tắt của không đồng bộ. Điều đó có nghĩa rằng trong mã ban đầu của bạn, saveRecord sẽ được thực hiện trước khách hàng sẽ nhận được phản hồi từ máy chủ (và, tùy thuộc vào việc thực hiện $.ajax, có thể trước khi khách hàng gửi yêu cầu tới máy chủ).

Ngoài ra, bạn có vẻ hiểu sai cách các hàm hoạt động trong JS. var category = autoSelectCategory(payee); sẽ đặt danh mục thành giá trị trả lại là autoSelectCategory; nhưng hàm autoSelectCategory trong mã của bạn không trả về gì cả.

Từ phía bên kia, giá trị trả về của hàm ẩn danh data chỉ có thể được sử dụng bởi hàm $.ajax (và $.ajax có thể bỏ qua giá trị trả về tham số success).

Dưới đây là đoạn code mà nên làm việc:

function parseRow(row){ 
    var rowArray  = row.trim().split(","); 
    var date   = rowArray[0]; 
    var checknum  = rowArray[1]; 
    var payee  = rowArray[2]; 
    var memo   = rowArray[3]; 
    var amount  = rowArray[4]; 

    autoSelectCategory(payee, function (category) {  
     saveRecord(date, checkNum, payee, memo, category, payment, deposit); 
    }); 
} 

function autoSelectCategory(payee, callback) { 
    $.ajax({ 
     async: false, 
     url: "autoselectcategory", 
     dataType: "json", 
     data: { 
      string: payee 
     }, 
     success: callback 
    }); 
} 
+1

Vì anh ta đang sử dụng 'async: false', sau đó thực sự 'saveRecord' ** sẽ không ** được thực hiện trước khi' $ .ajax' kết thúc công việc. Ông * là * trả về giá trị không chính xác mặc dù. Định nghĩa 'var data;' trước '$ .ajax', thiết lập nó trong' success' và trả về sau '$ .ajax' sẽ hoạt động. Tuy nhiên, thực hành ** thực sự tồi tệ của nó để sử dụng 'async: false'. – freakish

+0

@freakish Tôi nên chú ý đến 'async: false'. Thậm chí không biết điều đó là có thể :) – penartur

+0

Cảm ơn cả hai! Chính xác những gì tôi đang tìm kiếm! – glassfish

9

Không sử dụng async: false tùy chọn. Đó là một cái ác thuần túy (khối tất cả các tập lệnh trong trình duyệt và thậm chí cả các tab khác!) Và nó không được dùng nữa kể từ jQuery 1.8. Bạn nên sử dụng callbacks như nó luôn luôn có nghĩa là để được.

function parseRow(row) { 
    /* the other code */ 
    autoSelectCategory(payee, function() { 
     saveRecord(date, checkNum, payee, memo, category, payment, deposit); 
    }); 
} 

function autoSelectCategory(payee, callback) { // <---- note the additional arg 
    $.ajax({ 
     url: "autoselectcategory", 
     dataType: "json", 
     data: { 
      string: payee 
     }, 
     success: function(res) { 
      /* the other code */ 
      callback(); 
     } 
    }); 
} 
Các vấn đề liên quan