Последовательное асинхронное выполнение.
День добрый всем заглянувшим.
Проблема: Умею 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, время: 05:27. |