Cách đặt thời gian chờ http toàn cầu trong AngularJs


76

Tôi biết tôi có thể đặt thời gian chờ mỗi và mọi lúc:

$http.get('path/to/service', {timeout: 5000});

... nhưng tôi muốn đặt thời gian chờ toàn cầu để giữ cho mã của mình KHÔ.


Tôi nghĩ rằng thực sự có một lý do cho điều đó. Máy chủ thường có điểm cuối nhanh và chậm và tôi đoán nhóm góc cạnh không muốn mọi người có thời gian chờ chậm nhất có thể ngay cả đối với các cuộc gọi thường phải nhanh
OlivierM 22/02/15

1
bạn có thể tạo một dịch vụ thực hiện các yêu cầu http, gửi cho nó phương thức, url và dữ liệu và bên trong nó triển khai bất kỳ cấu hình mặc định nào bạn muốn, tốt hơn là bạn nên bao gồm miền của url và chỉ chuyển phần còn lại của nó và nó gắn chúng vào url hoàn chỉnh
Mohamed Selim

1
cách đặt thời gian chờ cho phương pháp đăng bài$http.post('path/to/service', {data:data});
ganesh

Câu trả lời:


41

CẬP NHẬT : $ http sẽ không tôn trọng cài đặt mặc định cho thời gian chờ đặt nó trong httpProvider (xem nhận xét). Giải pháp khả thi: https://gist.github.com/adnan-i/5014277

Câu trả lời ban đầu:

angular.module('MyApp', [])
  .config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.timeout = 5000;
}]);

1
Có chắc chắn rằng mã trên đang hoạt động? Có vẻ như config.timeout không được sửa đổi khi gọi sendReq: github.com/angular/angular.js/blob/master/src/ng/http.js#L550 So sánh với defaults.withCredentials một vài dòng ở trên, rằng sẽ dự phòng theo mặc định.
orjan

@orjan Chà, phần trên sẽ không tự hoạt động, nếu đó là những gì bạn đang hỏi. Đoạn mã chỉ hiển thị một tùy chọn cấu hình cho dự án Angular của riêng bạn. Để biết thêm thông tin, bạn có thể xem phần 'Đặt tiêu đề HTTP' và 'Tham số' tại docs.angularjs.org/api/ng.$http
Stewie

1
Tôi biết về ví dụ cấu hình của nó và mã không tự chạy. Tôi cũng biết về các giá trị mặc định cho tiêu đề và với Thông tin đăng nhập. Nhưng tôi không nghĩ rằng các mặc định đang hoạt động trong thời gian chờ. Tôi đã tạo jsfiddle: jsfiddle.net/RYDMM/4 đang cố gắng tái tạo sự cố, nhưng có vẻ như thời gian chờ hoàn toàn không ảnh hưởng đến jsonp
orjan 22/02/13

Đây là ý chính đang cố gắng giải thích rằng không thể đặt thời gian chờ mặc định: gist.github.com/orjan/5013478
orjan 22/02/13

2
@orjan Bạn hoàn toàn đúng. Tôi đã dựa vào tài liệu wile để cung cấp câu trả lời nhưng một lần nữa điều này chứng minh rằng tài liệu Angular không nên dựa vào. Sau khi xem qua nguồn ( github.com/angular/angular.js/blob/master/src/ng/http.js#L759 ), tôi có thể xác nhận phát hiện của bạn - không thể đặt thời gian chờ toàn cầu bằng cách sử dụng $ httpProvider. giá trị mặc định. Cảm ơn bạn orjan, vì sự siêng năng của bạn. Tôi sẽ cập nhật câu trả lời của mình để đưa ra cách giải quyết khác: gist.github.com/adnan-i/5014277
Stewie

105

Điều này có thể thực hiện được với angle.js đang chảy máu (được thử nghiệm với git master 4ae46814ff).

Bạn có thể sử dụng trình chặn yêu cầu http. Như thế này.

 angular.module('yourapp')
  .factory('timeoutHttpIntercept', function ($rootScope, $q) {
    return {
      'request': function(config) {
        config.timeout = 10000;
        return config;
      }
    };
 });

Và sau đó trong .config tiêm $ httpProvider và thực hiện việc này:

$httpProvider.interceptors.push('timeoutHttpIntercept');

6
Công trình như một nét duyên dáng và nên là câu trả lời được chấp nhận vì nó là 2 năm sau bây giờ ....
Sebastian J.

2
Không quan tâm, tại sao bạn lại tiêm $ rootScope và $ q? hay những thứ này được sử dụng bên ngoài mã bạn đã dán?
Ben Taliadoros

1
Ngoài ra, làm thế nào để bạn xử lý điều này? Tôi nhận thấy yêu cầu đã bị hủy, tôi có thể đặt người nghe cho việc này không?
Ben Taliadoros

câu trả lời tốt nhất không được hỗ trợ đầy đủ bởi phiên bản thực tế. Vui lòng cập nhật câu trả lời của bạn bằng cách loại bỏ dòng đầu tiên nói về phiên bản góc
Nicolas Janel

5
config.timeout = config.timeout || 10000;
Alexander Atanasov

9

Cảm ơn cho bài đăng và cập nhật !!

Khi nghiên cứu vấn đề này một cách cụ thể $resource, tôi nghĩ rằng tôi đã giải thích kỹ càng những gì tôi đã tìm thấy:

  • Sự cố này đã được đăng nhập trong trình theo dõi và trong góc 1.1.5, có hỗ trợ chuyển thuộc tính thời gian chờ đến $httpyêu cầu:

https://github.com/angular/angular.js/issues/2190 http://code.angularjs.org/1.1.5/docs/api/ngResource.$resource

  • Đối với những người trong chúng ta trên các phiên bản trước đó, cụ thể là tôi đang sử dụng angle 1.0.6, có thể chỉnh sửa tệp nguồn cho angle-resource.js trên dòng 396, bạn sẽ tìm thấy lệnh gọi đến $httpnơi bạn có thể tự thêm thuộc tính thời gian chờ cho tất cả yêu cầu tài nguyên.

  • Vì nó không được đề cập và tôi phải thử nghiệm giải pháp của Stewie, khi thời gian chờ xảy ra, cách để phân biệt giữa lỗi và hủy bỏ / thời gian chờ là kiểm tra đối số 'trạng thái'. Nó sẽ trả về 0cho thời gian chờ thay vì nói 404:

    $http.get("/home", { timeout: 100 })
    .error(function(data, status, headers, config){
            console.log(status)
        }
    
  • Vì chỉ có một số trường hợp tôi cần sử dụng thời gian chờ thay vì đặt nó trên toàn cầu, tôi đang gói các yêu cầu trong một $timeouthàm, như sau:

    //errorHandler gets called wether it's a timeout or resource call fails
    
    var t = $timeout(errorHandler, 5000);
    myResource.$get( successHandler, errorHandler )   
    function successHandler(data){
        $timeout.cancel(t);
        //do something with data...
    }
    
    function errorHandler(data){
        //custom error handle code
    } 
    

1
+! để biết "cách phân biệt giữa lỗi và hủy bỏ / thời gian chờ"
Bennett McElwee

1

Tôi có cùng yêu cầu và tôi đang sử dụng AngularJS 1.0.7. Tôi đã nghĩ ra đoạn mã dưới đây vì không có giải pháp nào ở trên có vẻ khả thi đối với tôi (khả thi theo nghĩa tôi muốn thời gian chờ diễn ra trên toàn cầu tại một nơi). Về cơ bản, tôi đang che $ http phương pháp ban đầu và bổ sung timeoutcho mỗi $httpyêu cầu và trọng phương pháp tắt khác, như get, post, ... để họ sẽ sử dụng mới đeo mặt nạ $http.

JSFiddle cho mã bên dưới:

/**
 * @name ngx$httpTimeoutModule
 * @description Decorates AngularJS $http service to set timeout for each
 * Ajax request.
 * 
 * Implementation notes: replace this with correct approach, once migrated to Angular 1.1.5+
 * 
 * @author Manikanta G
 */
;(function () {
    'use strict';

    var ngx$httpTimeoutModule = angular.module('ngx$httpTimeoutModule', []);

    ngx$httpTimeoutModule.provider('ngx$httpTimeout', function () {
        var self = this;
        this.config = {
            timeout: 1000 // default - 1 sec, in millis
        };

        this.$get = function () {
            return {
                config: self.config
            };
        };
    });

    /** 
     * AngularJS $http service decorator to add timeout
     */
    ngx$httpTimeoutModule.config(['$provide',  function($provide) {

        // configure $http provider to convert 'PUT', 'DELETE' methods to 'POST' requests
        $provide.decorator('$http', ['$delegate', 'ngx$httpTimeout', function($http, ngx$httpTimeout) {
            // create function which overrides $http function

            var _$http = $http;

            $http = function (config) {
                config.timeout = ngx$httpTimeout.config.timeout;
                return _$http(config);
            };
            $http.pendingRequests = _$http.pendingRequests;
            $http.defaults = _$http.defaults;

            // code copied from angular.js $HttpProvider function
            createShortMethods('get', 'delete', 'head', 'jsonp');
            createShortMethodsWithData('post', 'put');

            function createShortMethods(names) {
                angular.forEach(arguments, function(name) {
                    $http[name] = function(url, config) {
                        return $http(angular.extend(config || {}, {
                            method : name,
                            url : url
                        }));
                    };
                });
            }

            function createShortMethodsWithData(name) {
                angular.forEach(arguments, function(name) {
                    $http[name] = function(url, data, config) {
                        return $http(angular.extend(config || {}, {
                            method : name,
                            url : url,
                            data : data
                        }));
                    };
                });
            }

            return $http;
        }]);

    }]);

})();

Thêm phụ thuộc vào mô-đun trên và định cấu hình thời gian chờ bằng cách định cấu hình ngx$httpTimeoutProvider, như bên dưới:

angular.module('App', ['ngx$httpTimeoutModule']).config([ 'ngx$httpTimeoutProvider', function(ngx$httpTimeoutProvider) {
    // config timeout for $http requests
    ngx$httpTimeoutProvider.config.timeout = 300000; // 5min (5 min * 60 sec * 1000 millis)

} ]);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.