(task: Task)
| 131 | const SCHEDULED = 'scheduled'; |
| 132 | |
| 133 | function scheduleTask(task: Task) { |
| 134 | const data = <XHROptions>task.data; |
| 135 | const target = data.target; |
| 136 | target[XHR_SCHEDULED] = false; |
| 137 | target[XHR_ERROR_BEFORE_SCHEDULED] = false; |
| 138 | // remove existing event listener |
| 139 | const listener = target[XHR_LISTENER]; |
| 140 | if (!oriAddListener) { |
| 141 | oriAddListener = target[ZONE_SYMBOL_ADD_EVENT_LISTENER]; |
| 142 | oriRemoveListener = target[ZONE_SYMBOL_REMOVE_EVENT_LISTENER]; |
| 143 | } |
| 144 | |
| 145 | if (listener) { |
| 146 | oriRemoveListener.call(target, READY_STATE_CHANGE, listener); |
| 147 | } |
| 148 | const newListener = (target[XHR_LISTENER] = () => { |
| 149 | if (target.readyState === target.DONE) { |
| 150 | // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with |
| 151 | // readyState=4 multiple times, so we need to check task state here |
| 152 | if (!data.aborted && target[XHR_SCHEDULED] && task.state === SCHEDULED) { |
| 153 | // check whether the xhr has registered onload listener |
| 154 | // if that is the case, the task should invoke after all |
| 155 | // onload listeners finish. |
| 156 | // Also if the request failed without response (status = 0), the load event handler |
| 157 | // will not be triggered, in that case, we should also invoke the placeholder callback |
| 158 | // to close the XMLHttpRequest::send macroTask. |
| 159 | // https://github.com/angular/angular/issues/38795 |
| 160 | const loadTasks = target[Zone.__symbol__('loadfalse')]; |
| 161 | if (target.status !== 0 && loadTasks && loadTasks.length > 0) { |
| 162 | const oriInvoke = task.invoke; |
| 163 | task.invoke = function () { |
| 164 | // need to load the tasks again, because in other |
| 165 | // load listener, they may remove themselves |
| 166 | const loadTasks = target[Zone.__symbol__('loadfalse')]; |
| 167 | for (let i = 0; i < loadTasks.length; i++) { |
| 168 | if (loadTasks[i] === task) { |
| 169 | loadTasks.splice(i, 1); |
| 170 | } |
| 171 | } |
| 172 | if (!data.aborted && task.state === SCHEDULED) { |
| 173 | oriInvoke.call(task); |
| 174 | } |
| 175 | }; |
| 176 | loadTasks.push(task); |
| 177 | } else { |
| 178 | task.invoke(); |
| 179 | } |
| 180 | } else if (!data.aborted && target[XHR_SCHEDULED] === false) { |
| 181 | // error occurs when xhr.send() |
| 182 | target[XHR_ERROR_BEFORE_SCHEDULED] = true; |
| 183 | } |
| 184 | } |
| 185 | }); |
| 186 | oriAddListener.call(target, READY_STATE_CHANGE, newListener); |
| 187 | |
| 188 | const storedTask: Task = target[XHR_TASK]; |
| 189 | if (!storedTask) { |
| 190 | target[XHR_TASK] = task; |
nothing calls this directly
no test coverage detected
searching dependent graphs…