Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Fetch :: Stream (https://javascript.ru/forum/misc/72852-fetch-stream.html)

xShift 03.03.2018 00:00

Fetch :: Stream
 
Начал изучать стримы и напоролся на интересный момент: если мы из 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 );

		});

Aetae 03.03.2018 00:12

Если это нужно только для полоски загрузки - хватит банального xmlhttp, и не надо будет городить огород.)

xShift 03.03.2018 08:56

Хочется именно на fetch.

Aetae 03.03.2018 13:55

Цитата:

- Надо забить гвоздь - микроскопом как-то сложно выходит, подскажите как лучше?
- Попробуйте молотком.
- Нет, хочется именно микроскопом.
Ну тогда возись с преобразованиями. *пожал плечами*

xShift 03.03.2018 14:10

Я думал, кто хитрее подскажет способ, но видимо не вариант. Спасибо


Часовой пояс GMT +3, время: 16:19.