LINUX.ORG.RU

«Синхронная» работа с XMLHttpRequest в js

 ,


0

2

Привет!

Столкнулся с необходимостью написания небольшой поделки, которая использует javascript. У меня есть список item'ов, мне нужно по каждому из них сделать запрос к внешнему сервису и результат показать табличкой типа «| item | результат запроса |». Запросы выполняю через XMLHttpRequest. Так вот при работе с ним синхронно все получается так, как я и хочу - я по каждому элементу списка создаю новую строку таблицы через js, в первую колонку пишу item, выполняю запрос, результат записываю во вторую колонку, и перехожу к следующему элементу. И все хорошо, только вот консоль мне постоянно ругается «э ты чо в 2К18 никто не пишет синхронно быстро переделывай посоны засмеют», если мне нужно больше чем одну таких таблички сделать то js (ну движок браузера или что там) видно не умеет нормально параллелить запросы и все это постоянно отваливается с чудесным «NetworkError: A network error occurred.», ну и вообще в интернетах все советуют забыть про синхронные запросы.

Итак, что мне делать? Я не хочу чтоб у меня эти коллбэки ехали через коллбэки и коллбэками погоняли, мне в целом все равно сколько будет занимать загрузка страницы (с кучей элементов и синхронно это порядка секунды, потому что все на локалхосте), как-то можно делать запрос асинхронно, при этом дожидаться результатов его выполнения (код, который получает данные из «удаленного» источника собран в функцию, которая (грубо говоря) на вход получает урл и параметры, и возвращает текст ответа).

Заранее спасибо за советы!

Ответ на: комментарий от static_lab

И чем это мне поможет? Если сразу за fetchAll я беру значение list - оно будет пустым, потому что вся эта асинхронная штуковина еще не отработала. А потом оно мне выдаст ответ в коллбэк (или в никуда). Я не могу обернуть этот код в функцию, которая вернет результат. И это ничем по факту не отличается от другой асинхронщины.

micronekodesu ★★ ()
Ответ на: комментарий от micronekodesu

Скоро в стандарте обещается глобальный await, а пока можешь завернуть основной код в async IIFE, и сделать await fetchAll(). Собственно потому-то я использование await в функции и показал.

static_lab ★★★★★ ()
Ответ на: комментарий от micronekodesu

Я не могу обернуть этот код в функцию, которая вернет результат.

Естественно. Асинхронный результат в принципе невозможно получить внутри синхронной функции, весь сахар с await только облегчает боль при увеличении числа асинхронных функций.

Но... задачи вида

Для каждого ЭЛЕМЕНТ из СПИСОК
    НОВАЯ_СТРОКА = ТАБЛИЦА.создать_новую_строку()
    ЯЧЕЙКА1 = НОВАЯ_СТРОКА.создать_ячейку()
    ЯЧЕЙКА2 = НОВАЯ_СТРОКА.создать_ячейку()
    ЯЧЕЙКА1.текст(ЭЛЕМЕНТ)
    ОТВЕТ = выполнить_запрос(урл, ЭЛЕМЕНТ)
    ЯЧЕЙКА2.текст(ОТВЕТ)

и без того решаются коллбэками: любой нормальный человекхипстер делает это через СПИСОК.forEach, поэтому асинхронщина не сильно отличается.

x3al ★★★★★ ()
Ответ на: комментарий от micronekodesu

Я не могу обернуть этот код в функцию, которая вернет результат

Ничего не поделаешь, диагноз — императивщина головного мозга, о чём тебе доктор консоль и говорит.

bodqhrohro_promo ()
Ответ на: комментарий от bodqhrohro_promo

Ничего не поделаешь, диагноз — императивщина головного мозга, о чём тебе доктор консоль и говорит.

Дык блин это и был основной вопрос треда, и в целом я ожидал один из двух вариантов в ответ - либо что синхронно я это делать не могу вообще (только асинхронно), либо что синхронно это делается так-то и так-то. Вместо этого мне тут напихали полный тред эвейтов, бабелов каких-то и прочего, приходится на все это убивать время чтоб увидеть что это опять та же самая асинхронщина или вообще что-то слишком далекое от сабжа.

micronekodesu ★★ ()
Ответ на: комментарий от micronekodesu

либо что синхронно я это делать не могу вообще

Так ты уже делаешь синхронно, только получаешь ворнинг и виснущую на время запроса вкладку, больше синхронных способов нету; жри свой вкусненький кактус дальше, медицина бессильна. </thread>

движок браузера или что там) видно не умеет нормально параллелить запросы

Здрасьтепривет, JS однопоточный, как они вообще должны параллелиться? Я б тебе воркеры предложил, чтоб меньше мучался, но в чроме в них синхронный XHR, оказывается, поломан, и всем насрать по описанным тобою причинам. Так что страдай. Можешь ещё попробовать вместо XHR скрытые айфреймы юзать, как до распространения и стандартизации аякса делали, или даже JSONP. Для императивного старпёра самое то.

bodqhrohro_promo ()
Ответ на: комментарий от bodqhrohro_promo

Для императивного старпёра самое то.

Ну жаль что у современных разработчиков следование каким-то выдуманным принципам важнее чем реальные задачи. Рад что столкнулся со всей этой ерундой на небольшом сайд-проекте и теперь буду обходить эти ваши фронты стороной.

Здрасьтепривет, JS однопоточный, как они вообще должны параллелиться?

Есть функция, которая делает синхронный запрос, получает ответ и возвращает его. Есть три функции, в которых эта функция используется, урлы разные, обработка ответов разная. Если я в скрипте пишу вызов как f1(); f2(); f3(); то я всегда получаю network error. Если я вызов f2 запихну в конец f1, а f3 буду вызывать из f2, то все работает нормально (кроме ругани на устаревшую синхронность в консоли). Я без понятия почему так и разбираться не хочу, но с моего дивана видно что функции в js запускаются («парсятся»\«интерпретируются») параллельно или что-то типа того, других объяснений я не вижу. Вот что я имел ввиду.

micronekodesu ★★ ()
Ответ на: комментарий от micronekodesu

следование каким-то выдуманным принципам

Но ведь это у тебя какая-то выдуманная колбэкофобия. Не можешь писать на JS — не берись. Надо — осваивай и не ной.

запускаются («парсятся»\«интерпретируются») параллельно или что-то типа того

Так не бывает. Синхронные блоки JS-кода всегда выполняются последовательно. Даже если ты, допустим, на один и тот же таймаут повешал несколько обработчиков — они выполнятся последовательно. Для параллелизации специально придумали воркеры, которые выполняются в изолированных контекстах.

Я без понятия почему так и разбираться не хочу

Воистину тут без кода хрен поймёшь, что ты там наворотил; вангую, что шатаешь один и тот же XHR-объект и что-то в нём портишь, причём так, что он у тебя просачивается в вызывающую функцию, причём при просачивании работает, а без — нет; копай в сторону области видимости, короче.

bodqhrohro_promo ()
Ответ на: комментарий от bodqhrohro_promo

хех, палочки, а не вилки, с вилками задача не работает - каждый берёт по вилке и все счастливы

eternal_sorrow ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.