Есть код, который состоит из трёх классов и функции ready(), которая работает с этими классами. Такой подход представляется мне разумным(хоть и многословным) потому что классы слабо связаны между собой и все промежуточные результаты сохраняются вне их. Таким образом ready() выполняет роль контроллера.
Проблема в том, что один из классов выполняет асинхронную операцию. Поэтому в контроллере ready() я применяю setTimeout(), с значением задержки 1000. Мне кажется, это плохой подход потому что на асинхронный запрос может понадобиться времени меньше 1000ms или больше(зависит от многих фактором, например скорости соединения).
js:
document.addEventListener("DOMContentLoaded", ready);
var file;
var addrArr = [];
function ready() {
var cSVDownloader = new CSVDownloader();
cSVDownloader.init();
setTimeout(function() {
var cSVConverter = new CSVConverter(file);
addrArr = cSVConverter.convertRawMapDataToArray();
var destroyedBuildings = new DestroyedBuildings('map', addrArr);
destroyedBuildings.createMap();
}, 1000);
};
function CSVDownloader() {...}
function CSVConverter() {...}
function DestroyedBuildings() {...}
Полный код здесь.
Один из вариантов, который поможет избавиться от этой неоднозначности - это помещение вызова cSVConverter.convertRawMapDataToArray() в success-функцию XMLHttpRequest-запроса. Но это плохой вариант потому что:
Представленный код я специально уменьшил до минимального размера(здесь всего 1 ajax-запрос) поэтому пожалуйста не подумайте, что вопрос в том как исправить именно этот код. Вопрос более общий.
Для сравнения: тут тот же самый код, но в котором происходит вызов одного класса из другого. Это то чего я хотел бы научиться избегать.
Советую использовать промисы (Promise) или async/await function.
в 1-ом случае
function ready() {
var cSVDownloader = new CSVDownloader();
cSVDownloader.init().then(function() {
//код начнет выполняться только в случае успешного выполнения асинхронной операции
var cSVConverter = new CSVConverter(file);
addrArr = cSVConverter.convertRawMapDataToArray();
var destroyedBuildings = new DestroyedBuildings('map', addrArr);
destroyedBuildings.createMap();
});
};
ссылка на промисы - https://learn.javascript.ru/promise
во 2-ом случае код примет вид:
async function ready() {
var cSVDownloader = new CSVDownloader();
await cSVDownloader.init()
//тут весь код отрабатывает сихронно
var cSVConverter = new CSVConverter(file);
addrArr = cSVConverter.convertRawMapDataToArray();
var destroyedBuildings = new DestroyedBuildings('map', addrArr);
destroyedBuildings.createMap();
});
};
ссылка на async/await - https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/async_function
Проще всего просто передавать функцию для обратного вызова не в setTimeout, а сразу в cSVDownloader.init
. Разумеется, нужно изменить эту функцию так, чтобы она вызывала переданный ей callback.
function ready() {
var cSVDownloader = new CSVDownloader();
cSVDownloader.init(function() {
var cSVConverter = new CSVConverter(file);
addrArr = cSVConverter.convertRawMapDataToArray();
var destroyedBuildings = new DestroyedBuildings('map', addrArr);
destroyedBuildings.createMap();
});
};
Также можно воспользоваться более современной технологией - обещаниями (Promise). Если cSVDownloader.init
будет возвращать обещание - то функцию ready можно будет написать так:
function ready() {
var cSVDownloader = new CSVDownloader();
cSVDownloader.init().then(function() {
var cSVConverter = new CSVConverter(file);
addrArr = cSVConverter.convertRawMapDataToArray();
var destroyedBuildings = new DestroyedBuildings('map', addrArr);
destroyedBuildings.createMap();
});
};
А в современных браузерах - даже так:
async function ready() {
var cSVDownloader = new CSVDownloader();
await cSVDownloader.init();
var cSVConverter = new CSVConverter(file);
addrArr = cSVConverter.convertRawMapDataToArray();
var destroyedBuildings = new DestroyedBuildings('map', addrArr);
destroyedBuildings.createMap();
};
Виртуальный выделенный сервер (VDS) становится отличным выбором
После загрузке страницы и установки соединения soketio у меня идут несколько emit подряд
Есть вот такой пример (код ниже) там при скролле шапка опускается вниз и если нажать на серые кнопки, то к элементам меню создаются цветные...