I'm trying to understand the Electron Main process. I'm confused about something.
Try this:
% touch blank.js
% electron blank.js
You will notice that electron does not exit. Since no 'app' has been created, it isn't clear to me why the process is sticking around, and why I need to call process.exit from blank.js to terminate. The documentation is a bit thin in describing main/browser extensions to process.
Say I have a typical electron app:
await app.whenReady();
const win = new BrowserWindow();
await win.loadUrl("https://google.com");
The window is created and the main method exits. Nothing else is awaiting anything. Electron doesn't exit in this case, because it doesn't make sense to since we're now just waiting on the user to interact with the window.
The things that should trigger an exit are the remaining window closing (window-all-closed event), or an explicit app.quit() type of command.
Now I guess you might say that this is different since a window actually got created, but how would Electron know that this will happen? For how long must it wait until it can be sure that no window will be created?
Establishing a rule like "the main method must await the window creation" seems overly-restrictive to me, so Electron just assumes that it might happen later or it might not, but until it's told to exit, it'll wait.
Ultimately, someone on the Electron team could give a more accurate answer, but this is my best guess.
I'm just getting started in programming and am using VSC and installed Node and am using it to run my files. My console.logs works, but I can't get return values when I invoke functions. What am I doing wrong?
Node.js is asynchronous. 99% of all functions you write are going to be "non-blocking". If you don't quite understand what that is, I highly suggest you google up on the node.js event loop, and what it means to be "asynchronous".
Once you figure that out, start using the async/await syntax, or "promise" syntax.
Edit:
I see you posted more information. Based on what you're doing, it actually has nothing to do with being asynchronous.
The problem is that you're just returning a string value of hihihihihi... and that's it. You don't print it out anywhere. You need to wrap your call to function a() inside console.log(). So like: console.log(a());
From within node.js I use the oriento module to access a OrientDB. In principle everything works fine, the only thing is the program dos not exit as it should. Here is the example:
const oriento = require("oriento");
const server = oriento({});
const db = server.use(dbname);
db.select("#rid").from("codelists").limit(1).scalar().then(function (result) {
console.dir(result);
}).finally(function () {
db.close();
server.close();
console.info("finished");
});
The programm executes the select, then the "then" and finally the "finally" clauses. All fine. But it does not exit. There seems to be something hanging on the event loop. But what? And how can I get rid of it? The problem actually is worse then just "press Ctrl-C" or have a process.exit() when everything is done, because the code is supposed to run within a unit test, where I cannot call exit. Any suggestions?
The problem is solved in the current master version of oriento. https://github.com/codemix/oriento/issues/170
You can use process._getActiveRequests() and process._getActiveHandles() to see what's holding the app open. They are undocumented but commonly used in this scenario.
Consider:
node -e "setTimeout(function() {console.log('abc'); }, 2000);"
This will actually wait for the timeout to fire before the program exits.
I am basically wondering if this means that node is intended to wait for all timeouts to complete before quitting.
Here is my situation. My client has a node.js server he's gonna run from Windows with a Shortcut icon. If the node app encounters an exceptional condition, it will typically instantly exit, not leaving enough time to see in the console what the error was, and this is bad.
My approach is to wrap the entire program with a try catch, so now it looks like this: try { (function () { ... })(); } catch (e) { console.log("EXCEPTION CAUGHT:", e); }, but of course this will also cause the program to immediately exit.
So at this point I want to leave about 10 seconds for the user to take a peek or screenshot of the exception before it quits.
I figure I should just use blocking sleep() through the npm module, but I discovered in testing that setting a timeout also seems to work. (i.e. why bother with a module if something builtin works?) I guess the significance of this isn't big, but I'm just curious about whether it is specified somewhere that node will actually wait for all timeouts to complete before quitting, so that I can feel safe doing this.
In general, node will wait for all timeouts to fire before quitting normally. Calling process.exit() will exit before the timeouts.
The details are part of libuv, but the documentation makes a vague comment about it:
http://nodejs.org/api/all.html#all_ref
you can call ref() to explicitly request the timer hold the program open
Putting all of the facts together, setTimeout by default is designed to hold the event loop open (so if that's the only thing pending, the program will wait). You can programmatically disable or re-enable the behavior.
Late answer, but a definite yes - Nodejs will wait around for setTimeout to finish - see this documentation. Coincidentally, there is also a way to not wait around for setTimeout, and that is by calling unref on the object returned from setTimeout or setInterval.
To summarize: if you want Nodejs to wait until the timeout has been called, there's nothing you need to do. If you want Nodejs to not wait for a particular timeout, call unref on it.
If node didn't wait for all setTimeout or setInterval calls to complete, you wouldn't be able to use them in simple scripts.
Once you tell node to listen for an event, as with the setTimeout or some async I/O call, the event loop will loop until it is told to exit.
Rather than wrap everything in a try/catch you can bind an event listener to process just as the example in the docs:
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
});
setTimeout(function() {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
In the uncaughtException event, you can then add a setTimeout to exit after 10 seconds:
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
setTimeout(function(){ process.exit(1); }, 10000);
});
If this exception is something you can recover from, you may want to look at domains: http://nodejs.org/api/domain.html
edit:
There may actually be another issue at hand: your client application doesn't do enough (or any?) logging. You can use log4js-node to write to a temp file or some application-specific location.
Easy way Solution:
Make a batch (.bat) file that starts nodejs
make a shortcut out of it
Why this is best. This way you client would run nodejs in command line. And even if nodejs program returns nothing would happen to command line.
Making bat file:
Make a text file
put START cmd.exe /k "node abc.js"
Save it
Rename It to abc.bat
make a shortcut or whatever.
Opening it will Open CommandLine and run nodejs file.
using settimeout for this is a bad idea.
The odd ones out are when you call process.exit() or there's an uncaught exception, as pointed out by Jim Schubert. Other than that, node will wait for the timeout to complete.
Node does remember timers, but only if it can keep track of them. At least that is my experience.
If you use setTimeout in an arrow / anonymous function I would recommend to keep track of your timers in an array, like:
=> {
timers.push(setTimeout(doThisLater, 2000));
}
and make sure let timers = []; isn't set in a method that will vanish, so i.e. globally.
I'm trying to find the most elegant way for my node.js app to die when something happens. In my particular case, I have a config file with certain require parameters that have to be met before the server can start and be properly configured.
One way I have found to do this is:
var die = function(msg){
console.log(msg)
process.exit(1);
}
die('Test end');
Is there a better way to handle this kind of situation?
better use console.error if you are doing process.exit immediately after.
console.log is non-blocking and puts your message into write queue where it is not processed because of exit()
update: console.log also blocks in latest versions (at least since 0.8.x).
If you want to abruptly exit then this will do just fine. If you want do any clean up you should do that first after which node.js will probably stop anyway, because nothing keeps event loop running.