2015-07-20 34 views
22

Tôi có kịch bản sau, tôi cần dữ liệu từ một url cụ thể. Tôi đã viết một hàm nhận tham số 'url'. Bên trong hàm tôi có phương thức $ http.get gọi hàm url. Dữ liệu sẽ được trả lại cho hàm gọicuộc gọi http đồng bộ trong angularJS

var getData = function (url) { 
    var data = ""; 

    $http.get(url) 
     .success(function(response, status, headers, config) { 
      data = response; 
     }) 
     .error(function(errResp) { 
      console.log("error fetching url"); 
     }); 
    return data; 
} 

Vấn đề như sau, $ http.get không đồng bộ, trước khi trả lời được tìm nạp, hàm trả về. Do đó hàm gọi sẽ nhận dữ liệu dưới dạng chuỗi rỗng. Làm cách nào để buộc hàm không trả lại cho đến khi dữ liệu được tìm nạp từ url?

+0

Có gì sai khi sử dụng gọi lại hoặc lời hứa như bình thường? – Marty

+1

Bạn có thể tự trả về thành công và chức năng lỗi có thể được sử dụng thêm ... – binariedMe

Trả lời

15

Hãy xem lời hứa để vượt qua vấn đề như vậy, bởi vì chúng được sử dụng tất cả khắp nơi, trong thế giới góc cạnh.

Bạn cần phải sử dụng $q

var getData = function (url) { 
    var data = ""; 
    var deferred = $q.defer(); 

    $http.get(url) 
     .success(function(response, status, headers, config) { 
      deferred.resolve(response); 
     }) 
     .error(function(errResp) { 
      deferred.reject({ message: "Really bad" }); 
     }); 
    return deferred.promise; 
} 

Dưới đây là một bài viết tốt đẹp trên promises and $q

UPDATE:

FYI, $http dịch vụ tự trả về một lời hứa, vì vậy $q không nhất thiết phải bắt buộc trong trường hợp này (và do đó là anti-pattern).

Nhưng đừng để đây là lý do để bỏ qua việc đọc khoảng $ q và lời hứa.

Vì vậy, các mã trên là tương đương với sau:

var getData = function (url) { 
    var data = ""; 
    return $http.get(url); 
} 
+0

làm cách nào để truy cập vào giá trị của lời hứa? – clearScreen

+0

Tại sao một downvote? Phần nào của câu trả lời là không thể chấp nhận/sai? – nalinc

+1

Đó là mẫu chống phổ biến, xem: https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns –

5

Một cách điển hình để làm những gì bạn muốn là như vậy:

var getData = function(url, callback) { 
    $http.get(url).success(function(response) { 
     callback && callback(response); 
    }); 
}; 

Được sử dụng như:

getData('/endpoint', function(data) { 
    console.log(data); 
}); 
4

Bạn chức năng dường như không cần thiết. Chỉ cần sử dụng $http.get(url), vì bạn không thực sự làm bất cứ điều gì khác trước khi bạn sử dụng nó anyway.

var url = 'foo/bar'; 

$http 
    .get(url) 
    .success(function(response, status, headers, config) { 
     $scope.data = response; 
    }) 
    .error(function(errResp) { 
     console.log("error fetching url"); 
    }); 

Hoặc nếu bạn cần truy cập lời hứa sau đó chỉ cần gán nó cho biến;

var promise = $http.get(url); 

// some other code.. 

promise.then(function(data){ 
    //.. do something with data 
}); 
8

Bạn có thể sử dụng phương pháp $ q.all() cũng để giải quyết vấn đề này

var requestPromise = []; 

var getData = function (url) { 
    var data = ""; 

    var httpPromise = $http.get(url) 
     .success(function(response, status, headers, config) { 
      data = response; 
     }) 
     .error(function(errResp) { 
      console.log("error fetching url"); 
     }); 

    requestPromise.push(httpPromise); 
} 

trong hàm gọi

$q.all(requestPromise).then(function(data) { 

    //this is entered only after http.get is successful 
}); 

hãy chắc chắn để bơm $ q như một sự phụ thuộc. Hy vọng nó sẽ giúp

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