Мы столкнулись с повторяющимся шаблоном дизайна в нашем приложении django / angular5.x, которое
заставили нас написать довольно много кода, который напрямую взаимодействует с XMLHttpRequest , и мы хотели посмотреть, придумал ли кто-нибудь лучшее решение.
Вот шаблон: отправьте запрос на сервер, который выполняет длительную операцию (скажем, 5 минут). Во время операции сервер выдает серию отчетов о проделанной работе, прежде чем ответить успешно / неудачно.
Для целей этого сценария, скажем, сервер только что выпустил серию отчетов о проделанной работе, таких как следующий код django / python:
def reports(request):
return StreamingHttpResponse(stream())
def stream():
for num in range(10):
yield '%d of 10\n' % num
# simulate random 10 - 30 second delay
time.sleep(random.randint(10, 30))
В Angular5.x у нас есть сервис для отчета о прогрессе с использованием шаблона наблюдателя:
@Injectable()
export class ProgressService {
constructor() { }
progress() {
let seen: number = 0;
return Observable.create(observer => {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 3 || xhr.readyState === 4) {
observer.next(xhr.responseText.substring(seen);
seen = xhr.responseText.length;
}
}
xhr.open('POST', '/dosomething', true);
xhr.send();
});
}
}
Этот код работает - но неправильно писать что-то подобное каждый раз, когда мы взаимодействуем с долго работающим сервисом.
Мы посмотрели на angular2 HttpClient и увидели, что у него есть опция reportProgress
, но, похоже, он предоставляет только HttpEventType.DownloadProgress , который не предоставляет доступ к responseText
видел до сих пор. Я видел некоторые ссылки на перехватчики, но не ясно, как нам нужно манипулировать ими, чтобы извлечь тело ответа, накопленное во время отчетов о ходе выполнения.
Не столкнулись ли мы с ограничением инфраструктуры HttpClient и разработали единственное жизнеспособное решение? Или мы упускаем что-то невероятно очевидное?