yzt
2023-05-26 2f70f6727314edd84d8ec2bfe3ce832803f1ea77
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
define([
    './util',
    '../errors/RequestTimeoutError',
    '../errors/CancelError',
    '../_base/array',
    '../has!host-browser?../_base/window:',
    '../has!host-browser?dom-addeventlistener?:../on:'
], function(util, RequestTimeoutError, CancelError, array, win, on){
    // avoid setting a timer per request. It degrades performance on IE
    // something fierece if we don't use unified loops.
    var _inFlightIntvl = null,
        _inFlight = [];
 
    function watchInFlight(){
        // summary:
        //      internal method that checks each inflight XMLHttpRequest to see
        //      if it has completed or if the timeout situation applies.
 
        var now = +(new Date);
 
        // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
        for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){
            var response = dfd.response,
                options = response.options;
            if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){
                _inFlight.splice(i--, 1);
                watch._onAction && watch._onAction();
            }else if(dfd.isReady && dfd.isReady(response)){
                _inFlight.splice(i--, 1);
                dfd.handleResponse(response);
                watch._onAction && watch._onAction();
            }else if(dfd.startTime){
                // did we timeout?
                if(dfd.startTime + (options.timeout || 0) < now){
                    _inFlight.splice(i--, 1);
                    // Cancel the request so the io module can do appropriate cleanup.
                    dfd.cancel(new RequestTimeoutError('Timeout exceeded', response));
                    watch._onAction && watch._onAction();
                }
            }
        }
 
        watch._onInFlight && watch._onInFlight(dfd);
 
        if(!_inFlight.length){
            clearInterval(_inFlightIntvl);
            _inFlightIntvl = null;
        }
    }
 
    function watch(dfd){
        // summary:
        //      Watches the io request represented by dfd to see if it completes.
        // dfd: Deferred
        //      The Deferred object to watch.
        // response: Object
        //      The object used as the value of the request promise.
        // validCheck: Function
        //      Function used to check if the IO request is still valid. Gets the dfd
        //      object as its only argument.
        // ioCheck: Function
        //      Function used to check if basic IO call worked. Gets the dfd
        //      object as its only argument.
        // resHandle: Function
        //      Function used to process response. Gets the dfd
        //      object as its only argument.
        if(dfd.response.options.timeout){
            dfd.startTime = +(new Date);
        }
 
        if(dfd.isFulfilled()){
            // bail out if the deferred is already fulfilled
            return;
        }
 
        _inFlight.push(dfd);
        if(!_inFlightIntvl){
            _inFlightIntvl = setInterval(watchInFlight, 50);
        }
 
        // handle sync requests separately from async:
        // http://bugs.dojotoolkit.org/ticket/8467
        if(dfd.response.options.sync){
            watchInFlight();
        }
    }
 
    watch.cancelAll = function cancelAll(){
        // summary:
        //      Cancels all pending IO requests, regardless of IO type
        try{
            array.forEach(_inFlight, function(dfd){
                try{
                    dfd.cancel(new CancelError('All requests canceled.'));
                }catch(e){}
            });
        }catch(e){}
    };
 
    if(win && on && win.doc.attachEvent){
        // Automatically call cancel all io calls on unload in IE
        // http://bugs.dojotoolkit.org/ticket/2357
        on(win.global, 'unload', function(){
            watch.cancelAll();
        });
    }
 
    return watch;
});