26.06.2016, 20:00
|
Новичок на форуме
|
|
Регистрация: 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 собственно решение - написать свой собственный скриптовый движок, но это довольно затратное решение.
|
|
27.06.2016, 00:41
|
Профессор
|
|
Регистрация: 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);
|
|
27.06.2016, 02:57
|
Новичок на форуме
|
|
Регистрация: 26.06.2016
Сообщений: 3
|
|
Вы меня неправильно поняли. Я не спрашиваю чем достать данные и какие обработчики ставить.
Скрипт уже работает в виде очереди.
Я спрашиваю, можно ли на Javascript написать приведённый мною код и добиться от него последовательного выполнения.
Чтобы после выполнения первой строки управление переходило на вторую.
Чтобы асинхронные операции не приходилось распределять по трём-четырём функциям.
Можно поставить вопрос проще - можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода?
PS пока единственным вариантом мне видится написание скриптового движка, в который будет загоняться этот код. Но возможности языков обширны и поэтому я спрашиваю - если ли более удобное и менее ресурсоёмкое решение?
Последний раз редактировалось Bepec, 27.06.2016 в 03:14.
|
|
27.06.2016, 06:43
|
Профессор
|
|
Регистрация: 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().
|
|
27.06.2016, 07:15
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
Bepec,
Цитата:
|
Можно поставить вопрос проще - можно ли добиться того, чтобы скрипт выполнялся асинхронно, при этом сохраняя последовательный вид кода?
|
Да, конечно можно. На фронте я использую генераторы и библиотеку co. Можно также использовать async/await фукции с подключенным Babel`ем. То есть ты пишешь код в синхронном виде, а выполняется он асинхронно.
https://learn.javascript.ru/generato...ный-код
|
|
27.06.2016, 08:10
|
|
Профессор
|
|
Регистрация: 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
|
|
27.06.2016, 08:19
|
|
Профессор
|
|
Регистрация: 18.05.2011
Сообщений: 1,207
|
|
Цитата:
|
Совсем недавно состоялся релиз ES7, в котором появилась конструкция async/await:
|
ссылочку на пруф можно? Не нахожу этого тут http://www.ecma-international.org/ec...7.0/index.html. Вижу, что await попал в категорию Future Reserved Words.
|
|
27.06.2016, 13:58
|
Новичок на форуме
|
|
Регистрация: 26.06.2016
Сообщений: 3
|
|
laimas - спасибо за ответ, так у меня сейчас и сделано, но это сложно для отслеживания и для изменения порядка команд, или добавления новой необходимо будет в нескольких функциях править цепочку.
destus - спасибо за ответ, похоже это именно то, что мне нужно. Почитаю.
Erolast - спасибо за ответ, почитаю.
|
|
27.06.2016, 16:33
|
|
Профессор
|
|
Регистрация: 24.09.2013
Сообщений: 1,436
|
|
Цитата:
|
ссылочку на пруф можно? Не нахожу этого тут
|
А... и правда, не вошел.
Энивей, он уже release candidate - это значит, что фича проработана и теперь ожидает фидбека, так что юзать можно смело.
Цитата:
|
спасибо за ответ, почитаю.
|
Я главное-то забыл скинуть - http://www.2ality.com/2016/02/async-functions.html
Собственно, async/await - это то же самое, что использование генераторов совместно с либой co, просто это родная конструкция языка, не надо ничего подключать.
|
|
|
|