How do you trace and visualize JavaScript Promises? - javascript

In writing a fairly large JavaScript module with lots of async operation all dealing with promises, it becomes quite difficult to debug and follow the flow/state of promises.
Are there any tools or frameworks for instrumenting tests or module code to give he a flow of all the Promises in my system? I'm using jQuery promises if it matters at all.

Off the top of my head, and stimulated by #MrLeap's idea to send messages to the console, how about a creating Deferreds via an "adapter" of your own design.
eg (embryonic and untested) :
var debugMode = true;
function DeferredAdapter(name) {
var dfrd = $.Deferred();
if(debugMode) {
dfrd.notify = function() {
console.log(name + ': notify');
if (arguments[0] && typeof arguments[0] == "string")
console.log(arguments[0]);
};
//similar for resolve
//similar for reject
}
return dfrd;
}
This way (when you've got it working), you can do extra stuff when debugging, with a simple mechanism to turn off the extra stuff in production code, without the need to go through all your code purging console.log() statements.

It would add quite a bit of development overhead, but if you're using node for the back end you can implement pretty robust asynchronous unit tests with vows.js. If you want to add even more work for yourself you could use vows to create mock versions of all your responses if you're using some other kind of server tech, and use it for testing and reporting. Using a node.js mock server also lets you do robust, enterprise^^ things like simulate certain requests failing to see how gracefully your front end responds to it.
I wish I had a better answer than this though; console.log and console.dir are your best friends. Cram your callbacks full of them so you can get an idea how long stuff takes to happen, and in what order they happen.

Related

Static/dynamic way to detect dangling promises

I know this problem has been dealt with so many times, but none of them seem to solve the issue of reliably detecting dangling promises (even those that resolve properly).
So I want to be able to figure out a way (whether at runtime or better at static time) to root out "dangling promises", especially of this class:
async function a() {
... do some async operation ...
}
async function b() {
a(); // forgot to call await on it
}
where I have accidentally forget to await on one function and some task that executes asynchronously doesn't get awaited on. Often times these types of bugs don't throw exceptions so I can't just use "unhandledRejection" and call it a day.
At this point after lots of desperate attempts I just need a way to detect this kinda faulty pattern at either (optimally) static/compile/lint time or at runtime. Runtime for me I think should work assuming I have good test coverage.
tl;dr basically, I'm searching for some code that would do something like the following:
Error: Potential dangling promise detected!
...
at b (/dangling.js:5:3)
For each dangling promise
My thought process
I first tried finding some static analysis library that would help to detect these things (theoretically it should be possible but I had no luck with finding such a thing). A while back I remember finding something in the depths of stackoverflow that talked about using some typescript checker to check for dangling promises, though now I can't find it anymore :( . Though at the time changing the entire codebase to typescript was a no-go. (Later I learned you can actually use tsc to typecheck javascript (given that you do some type annotation in comments))
Currently I was previously using node version 11, so I thought about using the node.js's async_hooks API and try to listen on events (apparently simply monkey patching the Promise constructor wouldn't work because node.js bypasses the Promise constructor when creating a Promise object to return from an async function). Using node v11, after a bit of code hackery here it seemed to work (though it's not very efficient cause it throws away a lot of promise optimization in the v8 engine, but it does the job). There was a small hiccup in this entire operation in that I had to still monkey patch the then/catch/finally functions of the Promise API to check if we are currently calling that function (somehow that worked with detecting some dangling promises).
Now enter node v12 (apparently I need this for certain other things that are breaking), and now that hackery (unsurprisingly) completely breaks. After scrutinizing the version diffs, seems like they optimized the await/async implementation. After narrowing down the reason, it seems like await no longer calls the then function of the promise and just directly does some native shenanigans (idk what really).
Now I'm actually kinda desperate for some solution (and maybe if Typescript has some way of type-checking these dangling promises, what was the option to enable this check? I know (tested) that tsc doesn't do this by default).
You are most likely looking for the no-floating-promises rule of typescript-eslint

Performance impact during the multiple callback functions after sending response

Can anyone help me understand the function of NodeJS and performance impact for the below scenario.
a. Making the request to Rest API end point "/api/XXX". In this request, i am returning the response triggering the asynchronous function like below.
function update(req, res) {
executeUpdate(req.body); //Asynchronous function
res.send(200);
}
b. In this, I send the response back without waiting for the function to complete and this function executing four mongodb updates of different collection.
Questions:
As I read, the NodeJS works on the single thread, how this
asynchronous function is executing?
If there are multiple requests for same end point, how will be the
performance impact of NodeJS?
How exactly the NodeJS handles the asynchronous function of each
request, because as the NodeJS is runs on the single thread, is there
any possibility of the memory issue?
In short, it depends on what you are doing in your function.
The synchronous functions in node are executed on main thread, thus,
they will not preempt and execute until end of the function or until
return statement is encountered.
The async functions, on the other hand, are removed from main thread,
and will only be executed when async tasks are completed on a
separate worker thread.
There are, I think, two different parts in the answer to your question.
Actual Performance - which includes CPU & memory performance. It also obviously includes speed.
Understanding as the previous poster said, Sync and Async.
In dealing with #1 - actual performance the real only way to test it is to create or use a testing environment on your code. In a rudimentary way based upon the system you are using you can view some of the information in top (linux) or Glances will give you a basic idea of performance, but in order to know exactly what is going on you will need to apply some of the various testing environments or writing your own tests.
Approaching #2 - It is not only sync and async processes you have to understand, but also the ramifications of both. This includes the use of callbacks and promises.
It really all depends on the current process you are attempting to code. For instance, many Node programmers seem to prefer using promises when they make calls to MongoDB, especially when one requires more than one call based upon the return of the cursor.
There is really no written-in-stone formula for when you use sync or async processes. Avoiding callback hell is something all Node programmers try to do. Catching errors etc. is something you always need to be careful about. As I said some programmers will always opt for Promises or Async when dealing with returns of data. The famous Async library coupled with Bluebird are the choice of many for certain scenarios.
All that being said, and remember your question is general and therefore so is my answer, in order to properly know the implications on your performance, in memory, cpu and speed as well as in return of information or passing to the browser, it is a good idea to understand as best as you can sync, async, callbacks, promises and error catching. You will discover certain situations are great for sync (and much faster), while others do require async and/or promises.
Hope this helps somewhat.

Forever loop while waiting for asynchronous task?

I'm wondering if there's a way to cause JavaScript to wait for some variable-length code execution to finish before continuing using events and loops. Before answering with using timeouts, callbacks or referencing this as a duplicate, hear me out.
I want to expose a large API to a web worker. I want this API to feel 'native' in the sense that you can access each member using a getter which gets the information from the other thread. My initial idea was to compile the API and rebuild the entire object on the worker. While this works (and was a really fun project), it's slow at startup and cannot show changes made to the API without it being sent to the worker again after modification. Observers would solve part of this, and web workers transferrable objects would solve all, but they aren't adopted widely yet.
Since worker round-trip calls happen in a matter of milliseconds, I think stalling the thread for a few milliseconds may be an alright solution. Of course I would think about terminating in cases where calls take too long, but I'm trying to create a proof of concept first.
Let's say I want to expose the api object to the worker. I would define a getter for self.api which would fetch the first layer of properties. Each property would then be another getter and the process would continue until the final object is found.
worker.js
self.addEventListener('message', function(event) {
self.dataRecieved = true;
self.data = event.data; // would actually build new getters here
});
Object.defineProperty(self, 'api', {
get: function() {
self.dataRecieved = false;
self.postMessage('request api first-layer properties');
while(!self.dataRecieved);
return self.data; // whatever properties were received from host
}
});
For experimentation, we'll do a simple round-trip with no data processing:
index.html (only JS part)
var worker = new Worker("worker.js");
worker.onmessage = function() {
worker.postMessage();
};
If onmessage would interrupt the loop, the script should theoretically work. Then the worker could access objects like window.document.body.style on the fly.
My question really boils down to: is there a way to guarantee that an event will interrupt an executing code block?
From my understanding of events in JavaScript, I thought they did interrupt the current thread. Does it not because it's executing a blank statement over and over? What if I generated code to be executed and kept doing that until the data returned?
is there a way to guarantee that an event will interrupt an executing code block
As #slebetman suggests in comments, no, not in Javascript running in a browser's web-worker (with one possible exception that I can think of, see suggestion 3. below).
My suggestions, in decreasing order of preference:
Give up the desire to feel "native" (or maybe "local" might be a better term). Something like the infinite while loop that you suggest also seems to be very much fighting agains the cooperative multitasking environment offered by Javascript, including when thinking about a single web worker.
Communication between workers in Javascript is asynchronous. Perhaps it can fail, take longer than just a few milliseconds. I'm not sure what your use case is, but my feeling is that when the project grows, you might want to use those milliseconds for something else.
You could change your defined property to return a promise, and then the caller would do a .then on the response to retrieve the value, just like any other asynchronous API.
Angular Protractor/Webdriver has an API that uses a control flow to simulate a synchronous environment using promises, by always passing promises about. Taking the code from https://stackoverflow.com/a/22697369/1319998
browser.get(url);
var title = browser.getTitle();
expect(title).toEqual('My Title');
By my understanding, each line above adds a promise to the control flow to execute asynchronously. title isn't actually the title, but a promise that resolves to the title for example. While it looks like synchronous code, the getting and testing all happens asynchronously later.
You could implement something similar in the web worker. However, I do wonder whether it will be worth the effort. There would be a lot of code to do this, and I can't help feeling that the main consequence would be that it would end up harder to write code using this, and not easier, as there would be a lot of hidden behaviour.
The only thing that I know of that can be made synchronous in Javascript, is XMLHttpRequest when setting the async parameter to false https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Parameters. I wonder if you could come up with some sort of way to request to the server that maintains a connection with the main thread and pass data along that way. I have to say, my instinct is that this is quite an awful idea, and would be much slower than just requesting data from the main thread.
For what I know, there is not something native in JS to do this but it is relatively easy to do something similar. I made one some time ago for myself: https://github.com/xpy/whener/blob/master/whener.js .
You use it like when( condition, callback ) where condition is a function that should return true when your condition is met, and callback is the function that you want to execute at that time.

Breezejs, Browser freezes while manager assemples the objects

I have the following problem:
Breeze fetches metadata (23.4KB)
Breeze fetches lookups (4.5MB)
Right after lookups are downloaded, the browser will become unresponsive for about 30 seconds.
After this, everything works like a charm.
Why does breeze not use timeouts to inform the UI?
Firefox complains about long script operation, unresponsive, etc. The task manager (shows Firefox/Chrome/etc) as unresponsive.
Am I doing something wrong, or this is by design?
If this is by design, can i use a 'Web Worker' to do all the heavy operations and then return the whole model or something?
I tried something like this:
var test = function (name) {
return Q.fcall(function () {
setTimeout(function () {
toastr.success(name); // Notify me
return EntityQuery.from(name)
.using(manager).execute()
}, 1000) // This should be zero
});
};
var primeData = function (name) {
return test('Languages')
.then(test('dummy1'))
.then(test('dummy2'))
.then(test('dummy3'))
.then(test('dummy4'))
};
However the notifications seem to be poping up all at the same time, indicating that
return EntityQuery.from(name)
.using(manager).execute()
does not return when entity constuction finishes but when the JSON data for this entity arrived.
EDIT
Answer with webWorker provided here : BreezeJs with dedicated web worker
I think I see your point. Breeze hogs the UI thread while processing those thousands of arriving entities. If Breeze could somehow realize how much work it was doing, and would be doing, it could throw a timeout in there to give the UI a chance to breathe.
I'm not sure how safe that would be as Breeze would have to pick a moment that didn't leave the cache in an unstable state from someone's perspective.
I believe you can make this easier on yourself by breaking the one giant Lookups call into several smaller ones. You could still async await completion of all the smaller lookup promises if that is critical to your app. The fact that they are independent promise callbacks should give you the relief you seek.
Please try that and let us know how it works for you.
P.S.: You also have a cool opportunity here to optionally cache these lookups in local storage (indexdb) so you don't have to download them everytime. You'd need a versioning scheme of course and some plumbing so this lies in your future once things are looking good.

Node app.js - Reading files synchronously?

I've been reading through example applications try to learning node. And I've noticed that several use the readdirSync method when loading models and controllers on boot().
For instance:
var models_path = __dirname + '/app/models'
var model_files = fs.readdirSync(models_path)
model_files.forEach(function(file){
if (file == 'user.js')
User = require(models_path+'/'+file)
else
require(models_path+'/'+file)
})
This seems anti-node to me. It's the opposite of the "try-to-make-everything-async" that node favors.
When and why might synchronous file reads like this be a good idea?
More than likely, to make initialisation more simple—when asynchronicity for speed's sake doesn't matter; we're not trying to service many concurrent requests.
Similarly, if you need access to some variable which you're initialising on startup, which will be used for the life-time of the application, you don't want to have to wrap your entire app in a callback!
Synchronous reads are needed when you have to be certain that all of the data is available before you continue AND you need to keep a sequence in order. In other words if you NEED to have the process blocked and unable to do anything else (for anyone) such as when you are starting up a server (e.g. reading the certificate files for HTTPS).
Synchronous reads may be desirable at other time to keep the coding simpler as Len has suggested. But then you are trading off simplicity with performance as you suggest. In fact, it is better to make use of one of the many sequencing helper libraries in this case. These greatly simplify your code by taking care of nested callbacks and sequence issues.
And of course, the code you provide as an example is rather dangerous - what happens if the read fails?
Here are 3 of the libraries:
Streamline.js Allows you to write async js/coffeescript as though it were sync. Simply replace the callbacks with '_'. BUT you either have to compile your scripts or run them via a loader.
async - seems to be about the best thought out and documented and is recommended by a couple of people who have built real-world apps.
async.js - Chainable, exposes fs as well (includes readdir, walkfiles, glob, abspath, copy, rm - focused on fs rather than generic
This link may also be of use: The Tale of Harry - An explanation of how a mythical programmer moves from traditional programming to callback-based & the patterns that he ends up using. Also a useful insight into the patterns presented in the async library.

Categories