Начал изучать стримы и напоролся на интересный момент: если мы из fetch передаем в стрим response.body.getReader() то больше мы не можем использовать ни .text() ни json(). Свойство locked только read only.
Пытался Object.Assign, но ответ сервера тупо не копируется, хотя пишет что typeof object.
Нужно было сделать индикатор загрузки и напоролся на то что стрим отдает Unit8Array чанками, который нахрен не нужен.
Можно конечно коллектить чанки и потом клеить, но как вернуть больше 65xxx символов длины?
Вот... Есть идеи как обойтись одним потоком? Может как-то unit8array конвертировать? Сделал как-то неправильно и грузит в два потока, а например у GitHub полоска индикатора интереснее ....
Листинг:
var u = args[0] || null;
var m = args[1] || 'GET';
var d = args[2] || 'text';
var b = args[3] || null;
var f = args[4] || null;
// define what index of argument shold be used for callback
let callback = f ? f : b;
let headers = new Headers();
headers.append('X-Revolver', this.appVer);
let reqInit = {
method: m,
headers: headers,
cache: 'default',
credentials: 'same-origin',
mode: 'same-origin',
redirect: 'follow',
referrer: 'client'
};
if( m === 'POST' || m === 'PUT' && args[4] ) {
reqInit.body = b;
}
/* stream response */
function consume(reader, max) {
let total = 0;
return new Promise((resolve, reject) => {
function pump() {
reader.read().then(({done, value}) => {
if(done) {
RR.screenPosition(0.4, 1, true);
setTimeout(function(){
RR.screenPosition(0.7, 1, true);
}, 700);
setTimeout(function(){
RR.screenPosition(1, 1, true);
}, 800);
resolve();
return;
}
total += value.byteLength;
RR.screenPosition(total, max, true);
pump();
}).catch(reject);
}
pump();
});
}
const request = new Request(u, reqInit);
// indicate process loading
fetch(request).then(function(r) {
if(r.ok) consume(r.body.getReader(), r.headers.get("Content-Length"));
}).then(function(k) { });
// real data loading
fetch(request).then(function(r) {
if(r.ok) {
let result;
switch(d) {
default:
case 'text': result = r.text();
break;
case 'json': result = r.json();
break;
}
return result;
}
}).then(function(k) {
if( d === 'html' ) {
// revert from [string] to [object html]
const pattern = /<body[^>]*>((.|[\n\r])*)<\/body>/im;
k = RR.convertSTRToHTML(pattern.exec(k)[0]);
}
if( k ) callback.call( k );
});