2015-06-12 22 views
11

Có một cái nhìn vào đoạn mãLàm thế nào để tiêu diệt chưa được giải quyết lời hứa

$scope.getSongs = function(keyword){ 
    songServices.getSongList(keyword).then(
     function(resp){ 
      $scope.songList = resp.data.songList; 
     } 
    ); 
} 

Đây getSongList chỉ đơn giản trả về danh sách các bài hát từ máy chủ bằng cách yêu cầu HTTP.

Và trong HTML của tôi:

<input auto-focus type="text" placeholder="Enter song ID/Keyword" ng-model="keyword" ng-change="getSongs()"> 

Vấn đề ở đây là với hành vi của những lời hứa, đôi khi nếu một số lời hứa mất nhiều thời gian để có được giải quyết sau đó nó cho thấy dữ liệu sai (ngay cả trong ms.). khi bạn tìm kiếm 'AKON' cho phép lời hứa với cảnh cáo đầu tiên 'A' trả về lần cuối thì nó làm mới phạm vi bằng dữ liệu sai, Có cách nào để dừng hoặc hủy lời hứa chưa được giải quyết trước khi gửi lời hứa khác tới máy chủ hay không tôi có thể xử lý loại kịch bản như vậy không.

Xin cảm ơn trước.

+0

mà không đi vào đủ chi tiết để có câu trả lời, bạn có thể chuỗi lời hứa làm trung gian có thể được sử dụng để từ chối lời hứa đã lỗi thời. – zzzzBov

Trả lời

10

Các cuộc gọi $ http có thể bị hủy, bằng cách chuyển lời hứa trong tùy chọn cấu hình 'timeout' và giải quyết lời hứa đó.

Từ the documentation:

timeout - {số | Promise} - thời gian chờ trong mili giây, hoặc hứa rằng nên hủy bỏ yêu cầu khi giải quyết.

Ví dụ:

var canceler = $q.defer(); 
$http.get(someUrl, { timeout: canceler.promise }); 

// later: cancel the http request 

canceler.resolve(); 
6

Thay vì phá hủy lời hứa nó có thể là tốt hơn không thực hiện cuộc gọi đến khi người dùng đã ngừng gõ. bạn có thể sử dụng lệnh ng-options để đặt hẹn giờ gỡ lỗi. Bằng cách đó, hành động sẽ chỉ được thực hiện khi người dùng đã ngừng nhập.

<input auto-focus type="text" placeholder="Enter song ID/Keyword" ng-model="keyword" ng-change="getSongs" ng-model-options="{ debounce: 500}">

+1

Thay vì "thay vì", tôi muốn nói "Ngoài". Ngay cả khi yêu cầu thứ hai được gửi 500ms. sau lần đầu tiên, phản ứng của nó có thể đến sớm hơn. –

+0

Vấn đề là chúng ta không biết làm thế nào trừu tượng dịch vụ $ http được dựa trên ví dụ mã được cung cấp. Trên hết, nhóm nghiên cứu góc cạnh đã quyết định không thực hiện [hủy api] thực tế (https://github.com/angular/angular.js/pull/2452) với lời hứa $ q. Điều dễ nhất để anh ta làm là trả lại giá trị từ khóa đã được dịch vụ tìm kiếm và kiểm tra giá trị từ khóa hiện tại trên phạm vi $ và nếu chúng không khớp thì không cập nhật danh sách. –

2

Bạn có thể tạo ra một lời hứa bị phá hủy từ một lời hứa bình thường dễ dàng đủ:

var destroyablePromise = function(p) { 
    var r = $q.defer(); 

    p.then(function(a) { if (p) { r.resolve(a); }}, 
     function(a) { if (p) { r.reject(a); }}, 
     function(a) { if (p) { r.notify(a); }}); 

    r.promise.destroy = function() { 
    p = null; 
    }; 
    return r.promise; 
} 

Et thì đấy!

+0

Tôi thích giải pháp này, ban đầu tôi nghĩ rằng tôi sẽ cần phải từ chối lời hứa để hủy bỏ nó, nhưng đây là sự kiện tốt hơn, không có gì sẽ xảy ra! Có nguy cơ rò rỉ bộ nhớ với điều này? – pauloya

+0

Không có nguy cơ rò rỉ bộ nhớ _new_. Rõ ràng, nếu bạn bị rò rỉ 'r', bạn cũng bị rò rỉ' p'. – Malvolio

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