Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 26.06.2016, 20:00
Новичок на форуме
Отправить личное сообщение для Bepec Посмотреть профиль Найти все сообщения от Bepec
 
Регистрация: 26.06.2016
Сообщений: 3

Последовательное асинхронное выполнение.
День добрый всем заглянувшим.
Проблема:
Умею 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 собственно решение - написать свой собственный скриптовый движок, но это довольно затратное решение.
Ответить с цитированием
  #2 (permalink)  
Старый 27.06.2016, 00:41
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

waitToLoadPage(); - обрабатываем событие onload, после чего:
myAction(); - чего-то делаем
waitToText("Some text"); - асинхронный запрос сервера для получения "Some text", который обрабатываем после ответа сервера - XMLHttpRequest
myTextAction(); - чего-то делаем
waitToLoadData("Some filter"); - асинхронный запрос сервера для получения "Some filter", который обрабатываем после ответа сервера - XMLHttpRequest
var data = getData();
alert(data);
Ответить с цитированием
  #3 (permalink)  
Старый 27.06.2016, 02:57
Новичок на форуме
Отправить личное сообщение для Bepec Посмотреть профиль Найти все сообщения от Bepec
 
Регистрация: 26.06.2016
Сообщений: 3

Вы меня неправильно поняли. Я не спрашиваю чем достать данные и какие обработчики ставить.
Скрипт уже работает в виде очереди.

Я спрашиваю, можно ли на Javascript написать приведённый мною код и добиться от него последовательного выполнения.

Чтобы после выполнения первой строки управление переходило на вторую.
Чтобы асинхронные операции не приходилось распределять по трём-четырём функциям.

Можно поставить вопрос проще - можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода?

PS пока единственным вариантом мне видится написание скриптового движка, в который будет загоняться этот код. Но возможности языков обширны и поэтому я спрашиваю - если ли более удобное и менее ресурсоёмкое решение?

Последний раз редактировалось Bepec, 27.06.2016 в 03:14.
Ответить с цитированием
  #4 (permalink)  
Старый 27.06.2016, 06:43
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от Bepec
можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода?

Можно, при этом писать под каждый запрос сервера свой асинхронный запрос не обязательно. Вряд ли ваш последовательность бесконечна, а значит, если каждая 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().
Ответить с цитированием
  #5 (permalink)  
Старый 27.06.2016, 07:15
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Bepec,
Цитата:
Можно поставить вопрос проще - можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода?
Да, конечно можно. На фронте я использую генераторы и библиотеку co. Можно также использовать async/await фукции с подключенным Babel`ем. То есть ты пишешь код в синхронном виде, а выполняется он асинхронно.

https://learn.javascript.ru/generato...ный-код
Ответить с цитированием
  #6 (permalink)  
Старый 27.06.2016, 08:10
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

Цитата:
можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода?
Да. Совсем недавно состоялся релиз ES7, в котором появилась конструкция async/await:

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
Ответить с цитированием
  #7 (permalink)  
Старый 27.06.2016, 08:19
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Цитата:
Совсем недавно состоялся релиз ES7, в котором появилась конструкция async/await:
ссылочку на пруф можно? Не нахожу этого тут http://www.ecma-international.org/ec...7.0/index.html. Вижу, что await попал в категорию Future Reserved Words.
Ответить с цитированием
  #8 (permalink)  
Старый 27.06.2016, 13:58
Новичок на форуме
Отправить личное сообщение для Bepec Посмотреть профиль Найти все сообщения от Bepec
 
Регистрация: 26.06.2016
Сообщений: 3

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

destus - спасибо за ответ, похоже это именно то, что мне нужно. Почитаю.

Erolast - спасибо за ответ, почитаю.
Ответить с цитированием
  #9 (permalink)  
Старый 27.06.2016, 16:33
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

Цитата:
ссылочку на пруф можно? Не нахожу этого тут
А... и правда, не вошел.

Энивей, он уже release candidate - это значит, что фича проработана и теперь ожидает фидбека, так что юзать можно смело.

Цитата:
спасибо за ответ, почитаю.
Я главное-то забыл скинуть - http://www.2ality.com/2016/02/async-functions.html
Собственно, async/await - это то же самое, что использование генераторов совместно с либой co, просто это родная конструкция языка, не надо ничего подключать.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Последовательное выполнение JQuery Dionid Общие вопросы Javascript 0 13.07.2014 22:50
Последовательное выполнение Ajax запросов. jgunchenko AJAX и COMET 1 07.05.2014 12:50
Последовательное выполнение ajax запросов kaa AJAX и COMET 1 04.11.2013 19:59
Асинхронное выполнение скриптов в HTML RUVATA Общие вопросы Javascript 6 15.08.2011 13:34
Последовательное выполнение кода glutton Общие вопросы Javascript 3 09.11.2009 17:16