2011-08-25 37 views
5

tôi có mã này:nhận được dữ liệu từ chức năng async

function getData(){ 
     db.transaction(function(tx){ 
      tx.executeSql('SELECT * from q', [], function(tx, result){ 
       var q = []; 
       for (var i=0; i < result.rows.length; i++) { 
        q.push(result.rows.item(i)); 
       }; 
       console.log(q.length); // 3 
       returnData(q); 
      }); 
     }); 
    } 

    function returnData(data){ 
     console.log(data.length); // 3 
     return data; 
    } 

    var q = getData(); // undefined 

và nó không làm việc như mong đợi (nó không quay trở lại bất cứ điều gì). Giả sử đã xảy ra, bởi vì db.transaction hoạt động không đồng bộ, nhưng tôi đang sử dụng gọi lại để trả về dữ liệu. Ai đó có thể giải thích tại sao nó không hoạt động và cách khắc phục điều đó?

Trả lời

5

Cách thông thường để làm điều này là để bao gồm callback của riêng bạn, như thế này:

function getData(callback){ 
    db.transaction(function(tx){ 
     tx.executeSql('SELECT * from q', [], function(tx, result){ 
      var q = []; 
      for (var i=0; i < result.rows.length; i++) { 
       q.push(result.rows.item(i)); 
      }; 
      console.log(q.length); // 3 
      callback(returnData(q)); 
     }); 
    }); 
} 

function returnData(data){ 
    console.log(data.length); // 3 
    return data; 
} 

getData(function(q) { 
    /* do something with q */ 
}); 
+0

vì vậy, không có cách nào, để đặt mảng đó trong một biến ngoài hàm async? – nukl

+0

@nukl: Bạn có thể chỉ định các giá trị cho các biến trong bất kỳ phạm vi cao hơn nào (ví dụ: với các biến toàn cầu), nhưng điều này không giúp bạn. Điểm quan trọng khi sử dụng callbacks là * khi * dữ liệu được truy cập. Nếu bạn truy cập biến * trước * cuộc gọi lại được thực hiện (và giá trị được đặt), bạn sẽ nhận được sai hoặc không có dữ liệu. Có trường hợp sử dụng hoàn toàn hợp lệ để gán phản hồi cho các biến khác, bên ngoài hàm gọi lại, nhưng bạn phải nhận thức được ý nghĩa của việc thực hiện các cuộc gọi không đồng bộ. –

+0

@nukl, trừ khi bạn muốn sử dụng CoffeeScript (ngôn ngữ được biên dịch sang javascript): http://jashkenas.github.com/coffee-script/ –

0

Bạn không trả lại kết quả của bất kỳ hành động async, thay vào đó bạn lắng nghe nó.

Trong mã của bạn returnData không trả lại dữ liệu, nhưng bạn không làm bất cứ điều gì với kết quả, nó bị loại bỏ. Thay vào đó, bạn nên sử dụng gọi lại của riêng bạn.

function getData(callback){ 
    db.transaction(function(tx){ 
     tx.executeSql('SELECT * from q', [], function(tx, result){ 
      var q = []; 
      for (var i=0; i < result.rows.length; i++) { 
       q.push(result.rows.item(i)); 
      }; 
      console.log(q.length); // 3 
      callback(q); 
     }); 
    }); 
} 

var q; 
getData(function(data) { 
    console.log(data.length); // 3 
    console.log(data); 
    doStuffWith(data); 
    q = data; 
}); 
Các vấn đề liên quan