Последовательное асинхронное выполнение.
День добрый всем заглянувшим.
Проблема: Умею C++, не умею Javascript. И никак мне не удаётся понять, как можно (или с помощью чего) написать скрипт для автоматизации действий в браузере, с ожиданием загрузок страниц, паузами для загрузки данных и отработки скриптов. Пока на данный момент написал свой велосипед-менеджер в виде setInterval и очереди задач. Но такой код сложен для понимания, написания и фиг разберёшься в случае ошибок. Собственно я хочу писать примерно так(псевдокод): waitToLoadPage(); myAction(); waitToText("Some text"); myTextAction(); waitToLoadData("Some filter"); var data = getData(); alert(data); А пока получается только колбаса из очереди событий. function waitToLoadPage() { //some code insertQueue(myAction); } function myAction() { //some code insertQueue(waitToText); } function waitToText(text) { //some code insertQueue(myTextAction); } function myTextAction() { //some code insertQueue(waitToLoadData); } function waitToLoadData(data) { //some code insertQueue(getData); } function getData() { //some code alert(data); } И вопрос - как/чем лучше воспользоваться для реализации такого кода? Скорее всего есть готовые компоненты, но в javascript я новичек. PS собственно решение - написать свой собственный скриптовый движок, но это довольно затратное решение. |
waitToLoadPage(); - обрабатываем событие onload, после чего:
myAction(); - чего-то делаем waitToText("Some text"); - асинхронный запрос сервера для получения "Some text", который обрабатываем после ответа сервера - XMLHttpRequest myTextAction(); - чего-то делаем waitToLoadData("Some filter"); - асинхронный запрос сервера для получения "Some filter", который обрабатываем после ответа сервера - XMLHttpRequest var data = getData(); alert(data); |
Вы меня неправильно поняли. Я не спрашиваю чем достать данные и какие обработчики ставить.
Скрипт уже работает в виде очереди. Я спрашиваю, можно ли на Javascript написать приведённый мною код и добиться от него последовательного выполнения. Чтобы после выполнения первой строки управление переходило на вторую. Чтобы асинхронные операции не приходилось распределять по трём-четырём функциям. Можно поставить вопрос проще - можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода? PS пока единственным вариантом мне видится написание скриптового движка, в который будет загоняться этот код. Но возможности языков обширны и поэтому я спрашиваю - если ли более удобное и менее ресурсоёмкое решение? |
Цитата:
Можно, при этом писать под каждый запрос сервера свой асинхронный запрос не обязательно. Вряд ли ваш последовательность бесконечна, а значит, если каждая myAction(); индивидуальна, то их можно описать под именами связанными с параметром запроса. А каждый асинхронный запрос отличается как раз только значением этого параметра, как "руководство" для сервера и клиента. Можно и таймер, но если период запросов мал, то лучше запускать следующую myAction(); после завершения предыдущего запроса, который опираясь на параметрах текущего запроса вызовет следующий myAction(); Например: var f = { exe1 : function() { requestServer(2) }, exe2 : function() { requestServer(3) }, exe3 : function() { alert('End') } } function requestServer(p) { //асинхронный запрос с параметром var=p //получили и обработали ответ, запустили функцию f['exe'+p]() } Либо иначе, по иным условиям, запускайте свои myAction(). |
Bepec,
Цитата:
https://learn.javascript.ru/generato...ный-код |
Цитата:
main(); async function main() { await loadPage(); await myAction(); await text("Some text"); await myTextAction(); await loadData("Some filter"); var data = await getData(); alert(data); } async function waitToLoad() {}; async function myAction() {}; async function getData() { let request = await fetch("/api/data"); let data = await request.json(); return data; } А если вдруг надо связать код на async/await со старым, то используются обещания: function interval(ms) { //Если функция возвращает обещание, к ней можно применить await. return new Promise((resolve, reject) => { setInterval(resolve, ms); }); } await interval(1000); Собственно, сначала появились обещания, потом генераторы, и только потом, как синтаксический сахар над их связкой, async/await. А чтобы современный код можно было испольнять в старых браузерах, используется компиляция с помощью babel.js. Для чтения: https://developer.mozilla.org/ru/doc...bjects/Promise https://learn.javascript.ru/es-modern-usage |
Цитата:
|
laimas - спасибо за ответ, так у меня сейчас и сделано, но это сложно для отслеживания и для изменения порядка команд, или добавления новой необходимо будет в нескольких функциях править цепочку.
destus - спасибо за ответ, похоже это именно то, что мне нужно. Почитаю. Erolast - спасибо за ответ, почитаю. |
Цитата:
Энивей, он уже release candidate - это значит, что фича проработана и теперь ожидает фидбека, так что юзать можно смело. Цитата:
Собственно, async/await - это то же самое, что использование генераторов совместно с либой co, просто это родная конструкция языка, не надо ничего подключать. |
Часовой пояс GMT +3, время: 21:59. |