From f45a5db14278dcc4a7d1da483663931ae63f735c Mon Sep 17 00:00:00 2001 From: veeck Date: Sat, 1 Oct 2022 20:43:31 +0200 Subject: [PATCH 1/4] Convert loadFile to Promise --- js/loader.js | 90 +++++++++++++++++++++++----------------------------- js/module.js | 2 +- 2 files changed, 41 insertions(+), 51 deletions(-) diff --git a/js/loader.js b/js/loader.js index 70ed32c5fe..79142d8706 100644 --- a/js/loader.js +++ b/js/loader.js @@ -33,7 +33,7 @@ const Loader = (function () { // This is done after all the modules so we can // overwrite all the defined styles. - loadFile(config.customCss, function () { + loadFile(config.customCss).then(() => { // custom.css loaded. Start all modules. startModules(); }); @@ -137,7 +137,7 @@ const Loader = (function () { if (loadedModuleFiles.indexOf(url) !== -1) { afterLoad(); } else { - loadFile(url, function () { + loadFile(url).then(() => { loadedModuleFiles.push(url); afterLoad(); }); @@ -173,52 +173,45 @@ const Loader = (function () { * Load a script or stylesheet by adding it to the dom. * * @param {string} fileName Path of the file we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - const loadFile = function (fileName, callback) { + const loadFile = function (fileName) { const extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); let script, stylesheet; switch (extension.toLowerCase()) { case "js": - Log.log("Load script: " + fileName); - script = document.createElement("script"); - script.type = "text/javascript"; - script.src = fileName; - script.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - script.onerror = function () { - Log.error("Error on loading script:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("body")[0].appendChild(script); - break; + return new Promise((resolve, reject) => { + Log.log("Load script: " + fileName); + script = document.createElement("script"); + script.type = "text/javascript"; + script.src = fileName; + script.onload = function () { + resolve(); + }; + script.onerror = function () { + Log.error("Error on loading script:", fileName); + resolve(); + }; + document.getElementsByTagName("body")[0].appendChild(script); + }); case "css": - Log.log("Load stylesheet: " + fileName); - stylesheet = document.createElement("link"); - stylesheet.rel = "stylesheet"; - stylesheet.type = "text/css"; - stylesheet.href = fileName; - stylesheet.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - stylesheet.onerror = function () { - Log.error("Error on loading stylesheet:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("head")[0].appendChild(stylesheet); - break; + return new Promise((resolve, reject) => { + Log.log("Load stylesheet: " + fileName); + + stylesheet = document.createElement("link"); + stylesheet.rel = "stylesheet"; + stylesheet.type = "text/css"; + stylesheet.href = fileName; + stylesheet.onload = function () { + resolve(); + }; + stylesheet.onerror = function () { + Log.error("Error on loading stylesheet:", fileName); + resolve(); + }; + document.getElementsByTagName("head")[0].appendChild(stylesheet); + }); } }; @@ -237,35 +230,32 @@ const Loader = (function () { * * @param {string} fileName Path of the file we want to load. * @param {Module} module The module that calls the loadFile function. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - loadFile: function (fileName, module, callback) { + loadFile: function (fileName, module) { if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) { Log.log("File already loaded: " + fileName); - callback(); - return; + return Promise.resolve(); } if (fileName.indexOf("http://") === 0 || fileName.indexOf("https://") === 0 || fileName.indexOf("/") !== -1) { // This is an absolute or relative path. // Load it and then return. loadedFiles.push(fileName.toLowerCase()); - loadFile(fileName, callback); - return; + return loadFile(fileName); } if (vendor[fileName] !== undefined) { // This file is available in the vendor folder. // Load it from this vendor folder. loadedFiles.push(fileName.toLowerCase()); - loadFile(config.paths.vendor + "/" + vendor[fileName], callback); - return; + return loadFile(config.paths.vendor + "/" + vendor[fileName]); } // File not loaded yet. // Load it based on the module path. loadedFiles.push(fileName.toLowerCase()); - loadFile(module.file(fileName), callback); + return loadFile(module.file(fileName)); } }; })(); diff --git a/js/module.js b/js/module.js index 6d15452994..7c6c62a711 100644 --- a/js/module.js +++ b/js/module.js @@ -288,7 +288,7 @@ const Module = Class.extend({ const loadNextDependency = () => { if (dependencies.length > 0) { const nextDependency = dependencies[0]; - Loader.loadFile(nextDependency, this, () => { + Loader.loadFile(nextDependency, this).then(() => { dependencies = dependencies.slice(1); loadNextDependency(); }); From 2baf912e8374111bff7cfb97543a9d269d0dfe85 Mon Sep 17 00:00:00 2001 From: veeck Date: Thu, 26 Jan 2023 23:33:05 +0100 Subject: [PATCH 2/4] Convert loadConfig to async --- js/app.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/js/app.js b/js/app.js index 2f9e0b4979..cc4456c912 100644 --- a/js/app.js +++ b/js/app.js @@ -54,9 +54,9 @@ function App() { * Loads the config file. Combines it with the defaults, and runs the * callback with the found config as argument. * - * @param {Function} callback Function to be called after loading the config + * @returns {Promise<*>} */ - function loadConfig(callback) { + async function loadConfig() { Log.log("Loading config ..."); const defaults = require(`${__dirname}/defaults`); @@ -68,8 +68,7 @@ function App() { fs.accessSync(configFilename, fs.F_OK); const c = require(configFilename); checkDeprecatedOptions(c); - const config = Object.assign(defaults, c); - callback(config); + return Object.assign(defaults, c); } catch (e) { if (e.code === "ENOENT") { Log.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration.")); @@ -78,7 +77,7 @@ function App() { } else { Log.error(Utils.colors.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`)); } - callback(defaults); + return defaults; } } @@ -217,7 +216,7 @@ function App() { * @param {Function} callback Function to be called after start */ this.start = function (callback) { - loadConfig(function (c) { + loadConfig().then((c) => { config = c; Log.setLogLevel(config.logLevel); From e9d70e830a1a7c3cbc9d9e6a92a2a25207cca60e Mon Sep 17 00:00:00 2001 From: veeck Date: Thu, 26 Jan 2023 23:37:38 +0100 Subject: [PATCH 3/4] Convert start to async --- js/app.js | 76 +++++++++++++++++++++------------------------ js/electron.js | 4 +-- serveronly/index.js | 2 +- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/js/app.js b/js/app.js index cc4456c912..7cba0e45a8 100644 --- a/js/app.js +++ b/js/app.js @@ -211,58 +211,54 @@ function App() { * Start the core app. * * It loads the config, then it loads all modules. When it's done it - * executes the callback with the config as argument. + * executes the callback with the config as argument * - * @param {Function} callback Function to be called after start + * @returns {Promise<*>} */ - this.start = function (callback) { - loadConfig().then((c) => { - config = c; + this.start = async function () { + config = await loadConfig(); - Log.setLogLevel(config.logLevel); + Log.setLogLevel(config.logLevel); - let modules = []; + let modules = []; - for (const module of config.modules) { - if (!modules.includes(module.module) && !module.disabled) { - modules.push(module.module); - } + for (const module of config.modules) { + if (!modules.includes(module.module) && !module.disabled) { + modules.push(module.module); } + } - loadModules(modules, async function () { - httpServer = new Server(config); - const { app, io } = await httpServer.open(); - Log.log("Server started ..."); - - const nodePromises = []; - for (let nodeHelper of nodeHelpers) { - nodeHelper.setExpressApp(app); - nodeHelper.setSocketIO(io); - - try { - nodePromises.push(nodeHelper.start()); - } catch (error) { - Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); - Log.error(error); - } + loadModules(modules, async function () { + httpServer = new Server(config); + const { app, io } = await httpServer.open(); + Log.log("Server started ..."); + + const nodePromises = []; + for (let nodeHelper of nodeHelpers) { + nodeHelper.setExpressApp(app); + nodeHelper.setSocketIO(io); + + try { + nodePromises.push(nodeHelper.start()); + } catch (error) { + Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); + Log.error(error); } + } - Promise.allSettled(nodePromises).then((results) => { - // Log errors that happened during async node_helper startup - results.forEach((result) => { - if (result.status === "rejected") { - Log.error(result.reason); - } - }); - - Log.log("Sockets connected & modules started ..."); + Promise.allSettled(nodePromises).then((results) => { + // Log errors that happened during async node_helper startup + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } }); - }); - if (typeof callback === "function") { - callback(config); - } + Log.log("Sockets connected & modules started ..."); + }); }); + + return config; }; /** diff --git a/js/electron.js b/js/electron.js index 9e4d3f5e24..9e5e3f1815 100644 --- a/js/electron.js +++ b/js/electron.js @@ -177,7 +177,5 @@ app.on("certificate-error", (event, webContents, url, error, certificate, callba // Start the core application if server is run on localhost // This starts all node helpers and starts the webserver. if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].includes(config.address)) { - core.start(function (c) { - config = c; - }); + core.start().then((c) => (config = c)); } diff --git a/serveronly/index.js b/serveronly/index.js index 00d6b64be3..42cfd0496f 100644 --- a/serveronly/index.js +++ b/serveronly/index.js @@ -1,7 +1,7 @@ const app = require("../js/app.js"); const Log = require("logger"); -app.start((config) => { +app.start().then((config) => { const bindAddress = config.address ? config.address : "localhost"; const httpType = config.useHttps ? "https" : "http"; Log.log("\nReady to go! Please point your browser to: " + httpType + "://" + bindAddress + ":" + config.port); From 5d1773a8c1a67ad5e1ef0aba54ed087648fab301 Mon Sep 17 00:00:00 2001 From: veeck Date: Sat, 4 Feb 2023 21:19:39 +0100 Subject: [PATCH 4/4] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3964da9c82..dfe5b87166 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ _This release is scheduled to be released on 2023-04-01._ - Update weather tests - Changed updatenotification module for MagicMirror repo only: Send only notifications for `master` if there is a tag on a newer commit - Update dates in Calendar widgets every minute +- More callback -> async refactoring ### Fixed