Tasks in javascript? - javascript

Essence of the question
The real reason why I ask this question - not because I want solve my problem. I want to know how to work with tasks in JavaScript. I don't need thread paralleling and other stuff. There are two parts of computing smth: IO and CPU. I want to make CPU computing works in time between ajax request sended and ajax request get answer from server. There is obstacle: from one function I run many tasks and this function must produce Task, that waits all runned tasks, process results of them and returns some value. That's all I want. Of course, if you post another way to solve my problem, I will vote for your answer and can set it as solution if there are no other answers about tasks.
Why I describe my problem, not just asking about tasks? Ask guys who minused and closed this question a time ago.
Problem
My problem: I want to traverse a tree in JavaScript to find the smallest possible parsing. I have a dictionary of words stored in the form of a trie. When a user gives an input string, I need to get a count of words that match the input string and is the shortest combination of words.
Example:
My dictionary contains these words: my, code, js, myj, scode
A user types myjscode
I traverse my tree of words and find that the input matches myj + scode and my + js + code
Since the first parsing is the shortest, my function returns 2 (the number of words in the shortest parsing)
My Problem
My dictionary tree is huge, so I can't load it fully. To fix this, I want to do some lazy-loading. Each node of the tree is either loaded and points to child nodes or is not loaded yet and contains a link to the data to be loaded.
So, I need to make node look up calls while I'm traversing the tree. Since these calls are asynchronous, I want to be able to explore other traversals while loading tree nodes. This will improve the response time for the user.
How I want to solve this problem:
My lookup function will return a task. I can call that task and get its results. Once I traverse to the loaded node, I can then make multiple calls to load child nodes and each call returns a task. Since these "tasks" are individual bits of functionality, I can queue them up and execute them while I'm waiting for ajax calls to return.
So, I want to know which library I can use, or how I can emulate tasks in javascript (I'm thinking of tasks as they exist in C#).
There is restriction: no server-side code, only ajax to precompiled dictionaries in javascript. Why? It has to be used as password complexity checker.

You say in your question:
Of course, if you post another way to solve my problem, I will vote for your answer and can set it as solution if there are no other answers about tasks.
Good; sorry, but I don't think that c# style tasks is the right solution here.
I'll accept (although I don't think it's correct) your assertion that for security reasons you have to do everything client-side. As an aside, might I point out that if you are scared of somebody snooping (because you have a security weakness) then passing lots of requests for part of the password is just as insecure as passing one request? Sorry, I appear to have done so without consent!
Nonetheless, I will attempt to answer with a broad outline how I would approach your problem if, indeed, you had to do it in JavaScript; I would use promises. Probably jQuery's Deferred implementation, to be specific. I'll give a very rough pseudo-code outline here.
Overview
You start with a nicely structured Trie. Using recursion I would build up a nicely structured "solution tree", which would be a nested array of arrays; this would give the flexibility of being able to respond to the user with a specific message... however, since you seem prepared to lose that bonus and only want a single digit as a solution, I will outline a slightly simpler approach that you could, if needed, adapt to return arrays of the form (from your example):
[["myj"],["scode"],["my"],["js"],["code"]]
I mention this structure here also, partly, as it helps explain the approach I am adopting.
Notes
I will refer to "nodes" and "valueNodes" in your Trie. I consider "nodes" to be anything and "valueNodes" to be nodes with values.
The recursive promiseToResolveRemainder will resolve 0 for "couldn't do it"; it will only reject the promise if something went wrong (say, the webservice wasn't available).
Dodgy, hacky, untested Pseudo-code
var minDepth=0; //Zero value represents failure to match (Impossible? Not if you are accepting unicode passwords!)
function promiseToResolveRemainder(remainder,fragmentSoFar){
deferred = new jQuery.Deferred();
nextChar = remainder.substring(0,1);
if (remainder.length==1){
//Insert code here to:
//Test for fragmentSoFar+nextChar being a valueNode.
//If so, resolve(1)... otherwise resolve(0)
//!!Note that, subtly, this catches the case where fragmentSoFar is an empty string :)
return;
}
remainder = remainder.substring(1);
promiseToFindValueNode(fragmentSoFar+nextChar).then(
function(success){
//We know that we *could* terminate the growing fragment here and proceed
//But we could also proceed from here by adding to the fragment
var firstPathResolvedIn = 0;
var secondPathResolvedIn = 0;
promiseToResolveRemainder(remainder,'').then(
function(resolvedIn){
firstPathResolvedIn = resolvedIn + 1;
}
).then(
promiseToResolveRemainder(remainder,fragmentSoFar+nextChar).then(
function(resolvedIn){
secondPathResolvedIn = resolvedIn;
if(!firstPathResolvedIn==0 and !secondPathResolvedIn==0){
deffered.resolve(Math.min(firstPathResolvedIn,secondPathResolvedIn));
}
deferred.resolve(Math.max(firstPathResolvedIn,secondPathResolvedIn));//Sloppy, but promises cannot be resolved twice, so no sweat (I know, that's a *dirty* trick!)
}
)
)
},
function(failure){
//We know that we *need* at least a node or this call to
//promiseToResolveRemainder at this iteration has been a failure.
promiseToFindNode(fragmentSoFar+nextChar).then(
function(resolvedIn){
//ok, so we *could* proceed from here by adding to the fragment
promiseToResolveRemainder(remainder,fragmentSoFar+nextChar).then(
function(resolvedIn){
deferred.resolve(resolvedIn);
}
)
},
function(failedBecause){
//ooops! We've hit a dead end, we can't complete from here.
deferred.resolve(0);
}
)
},
)
return deferred.Promise();
}
I am not particularly proud of this untested kludgy attempt at code (and I'm not about to write your solution for you!), but I am proud of the approach and am sure that it will yield a robust, reliable and efficient solution to your problem. Unfortunately, you seem to be dependent on a lot of webService calls... I would be very tempted, therefore, to abstract away any calls to the webService and check them through a local cache first.

Not sure this is what you are looking for, but you might try WebWorkers.
A simple example is at: https://github.com/afshinm/50k but you can google for more.
Note - web workers will be highly browser dependent and do not run in a separate task on the machine.

Related

React JS - Best way to have coninues results for every key stroke using a REST calls to server?

In short we have a massive database and need to provide results as the user types them in the search box. It is impossible for us to preload queries and attempt to match that way.
Currently we send a request to the server with the new query string every 2 chars or 5 seconds. This is a bit of a mess however, so I'm looking to see if there is a faster/better way of doing this.
Previous solutions I've seen would require pre-feteching which in our case is not possible and considering the size of the return too costly.
I would recommend using debounce for this. It will make the function wait a certain amount of time after being called before running. Additional calls to the function will reset the timer. That way, the function will not run until users have finished (or paused) typing.
This which will prevent unnecessary load on your database, while still providing a good user experience (as long as you have a reasonable debounce time). Examples of how to do debounce in React can be found here

REST API Ajax simultaneously requests

Is it wrong to make multiple ajax simultaneously requests to different endpoints of a REST API that end up modifying the same resource?
Note: each endpoint will modify different properties.
For example, let's assume that one endpoint modifies some properties for an order, like order_date and amount and another endpoint set's the link between the same order and a customer by changing the customer_id value from the orders table (I know that maybe this is not the best example, all these updates can be done with one endpoint).
Thanks in advance!
This is totally a requirements based question. It is generally a bad idea to have a single resource be changed by multiple processes, but this ONLY matters if there is a consistency relationship between the data. Consider some of the following questions:
If one or more of the AJAX calls fails does will that break your application? If it will, then yes, this is a bad idea. Will your application carry on regardless of what data you have at any given time? If so, then no this doesn't matter.
Take some time to figure out what dependencies you have between your data calls and you will get your answer.
what you are describing is not a shared resource even if it is stored in the same object because you are modifying different properties however take great care when using same object. if your requests to the server depends on the properties that are modified by the other request.
in general its not a good idea to use the same object to store data that is modified by more than one asynchronous function even if the properties are different. it makes your code confusing and harder to maintain since you have to manually coordinate your function calls to prevent race condition.
there are better ways to manage your asynchronous code using Promises or Observables
It's a bad idea in general. But if your code is small and you can manage it then you can do it though its not recommended.
In the long run, it will cause you many problems confusion, maintaining code, consistency etc.
And if in any case another developer has to manage your code, It will be more confusing and tough for him.
In programming always keep things flexible and think in long run. Your requirements can change in future , what will you do then? write the whole program again? This is one thing , you also want to avoid.

Wait for AJAX to return success before continuing Javascript code?

A similar question has been asked many other times, I'm aware, but my case is rather specific and has, to my knowledge, never been touched on before. At least from what I can find.
What I'm doing is building objects using a UID. Everything that the object is built with requires this UID and it requires it to be verified as unique before anything can be done with it.
I'm randomly generating the UID in javascript and I'm checking it against all other entries in a SQL database. I'm posting to the database using PHP and Ajax.
The core issue I'm having is that Javascript doesn't wait for the Ajax response and instead just keeps rolling. Ajax has to use a success handler. This is strictly not possible for me to use because I cannot do anything until I know for certain that the UID is verified.
Are there any workarounds or solutions to this? Promises won't work because, as I stated before, the UID is integral in building the object in and of itself, so using placeholders won't work.
Thanks in advance!
You can just send a synchronous Ajax request, like that:
var response = $.ajax({ url : "http://api.jquery.com/jquery.ajax/", async : false });
(though that is not a very good practice)
Ok. One possible solution, if your UID is generated on the server randomly, you may supply it directly to your index.html with the script tag.
<head>
<script src="path_to_url_that_provides_generated_script"></script>
<script .... other scripts></script>
</head>
And this generated script would be something like:
var UID = "xxxx-xxxx-xxxx-xxxx";
That way you don't even need to do an ajax request, since your uid will known before any other script is processed.
The best method, I have discovered, was to rewrite my code to not begin object creation until I had the UID in the first place. While this does take up a considerable amount of time to complete and ensure that no unwieldy bugs are present, there's no other real solution that's both simple and effective.
As it turns out, foresight is something that always seems to keep good programmers from writing and rewriting their work again.
Special thanks to #Vladimir M for the solution.

Lift session-valid ajax callback from a static javascript

I am currently implementing a graph visualisation tool using lift on the server side and d3 ( a javascript visualisation framework) for all the visualisation. The problem I have is that in the script I want to get session dependent data from the server.
So basically, my objective is to write lift-valid ajax callbacks in a static js script.
What I have tried so far
If you feel that the best solution is one that I already tried feel free to post a detailed answer telling me how to use it exactly and how it completely solves my problem.
Write the ajax callback in another script using lift and call it from the main script
This solution, which is similar to a hidden text input is probably the more likely to work. However it is not elegant and it would mean that I would have to load a lot of scripts on load, which is not really conveniant.
This seems to be one of the prefered solutions in the lift community as explained in this discussion on the mailing list.
REST interface
Usually what one would do to get data from a javascript function in lift is to create a REST interface. However this interface will not be linked to any session. This is the solution I got from my previous question: Get json data in d3 from lift snippet
Give function as argument of script
Another solution would be to give the ajaxcallback as an argument of the main script called to generate my graph. However I expect to have a lot of callbacks and I don't want to have to mess with the arguments of my script.
Write the whole script in lift and then serve it to the client
This solution can be elegant, however my script is very long and I would really prefer that it remainss static.
What I want
On client side
While reviewing the source code of my webpage I found that the callback for an ajaxSelect is:
<select onchange="liftAjax.lift_ajaxHandler('F966066257023LYKF4=' + encodeURIComponent(this.value), null, null, null)" name="F96606625703QXTSWU" id="node_delete" class="input">
Moreover, there is a variable containing the state of the page in the end of the webpage:
var lift_page = "F96606625700QRXLDO";
So, I am wondering if it is possible to simulate that my ajaxcall is valid using this liftAjax.lift_ajaxHandler function. However I don't know the exact synthax to use.
On server side
Since I "forged" a request on client side, I would now like to get the request on client side and to dispatch it to the correct function. This is where the LiftRules.dispatch object seems the best solution: when it is called, all the session management has been made (the request is authentified and linked to a session), however I don't know how to write the correct piece of code in the append function.
Remark
In lift all names of variables are changed to a random string in order to increase the security, I would like to have the same behavior in my application even if that will probably mean that I will have to "give" the javascript these values. However an array of 15 string values is still a better tradeoff than 15 functions as argument of a javascript function.
Edit
While following my research I found this page : Mapping server functions to client actions which somehow explains the goal of named functions even if it stil didn't lead me to a working solution.
Quick Answer
Rest in Lift does not have to be stateless. If you register your RestHelper with LiftRules.dispatch.append, then it will be handled statefully and Session information will be available through the S object as usual.
Long Answer
Since you seem interested, and it's come up on SO before, here's a more detailed explanation of how server-side functions are registered and called in Lift. If you haven't worked with Lift for some time, look away. What follows should not in any way be used to evaluate Lift or its complexity. This is purely library developer level stuff and a majority of Lift users go about their development blissfully unaware of it.
How it works
When you create stateful callbacks, typically by using the methods within the SHtml object, what you are really doing is registering objects of type S.AFuncHolder within the context of the users session, each with a unique ID. The unique ID that was generated during this process is what you're seeing when you come across a pattern like F96606625700QRXLDO. When data is submitted, via form post, ajax, or whatever, Lift will check the request for these function ids and execute the associated function if they exist. There are several helpers that provide more specific types of AFuncHolder, like S.SFuncHolder (accepts a single string query parameter) and S.BinFuncHolder (parameter is multipart form data) but they all return Any and behind the scenes Lift will collect those return values to create the proper type of response. A JsCmd, for instance, will result in a JavaScriptResponse that executes the command. You can also return a LiftResponse directly.
How to use it
AFuncHolders are registered using the S.fmapFunc method. You'd call it like this
S.fmapFunc(SFuncHolder({ (str: String) =>
doSomethingAwesomeWithAString(str)
}))(id => <input type="text" name={id} value=""/>)
The first parameter is your function, wrapped in the proper *FuncHolder type and the second parameter is a function that takes the generated id and outputs something. The something that gets output is what you will include on the page. It should somehow result in the id being sent to the server as a query parameter so that your function is executed.
Putting it all together
You could use the above to make your own Ajax calls, but when Lift makes an ajax call there are a few other considerations:
1) Most browsers only allow so many simultaneous connections to a given domain. Three seems to be the magic number.
2) AFuncHolders will often close over the scope of the snippet they are contained within and if multiple ajax requests are handled at once, each in its own thread, bad things can happen.
To combat these issues, the liftAjax.lift_ajaxHandler function queues each ajax request, ensuring that only one at a time is sent to the server.
The drawback to this approach is that it can make it difficult to make an Ajax call where the result needs to be passed to a callback. JQuery autocomplete, for instance, provides a callback function when input changes that accepts a list of matches. If you are manually calling LiftAjax.lift_ajaxHandler though, you can provide your own callback functions for success & error and I would recommend that you look at the source of those functions in your browser for more information on how they work.
There's actually more to it, like how Lift restores RequestVars on ajax callbacks (which is where the lift_page comes in, but that's about all I'm prepared to explain over coffee on a Saturday morning :)
Good luck with your app!

What's a clean way to handle ajax success callbacks through a chain of object methods?

So, I'm trying to improve my javascript skills and get into using objects more (and correctly), so please bear with me, here.
So, take this example: http://jsfiddle.net/rootyb/mhYbw/
Here, I have a separate method for each of the following:
Loading the ajax data
Using the loaded ajax data
Obviously, I have to wait until the load is completed before I use the data, so I'm accessing it as a callback.
As I have it now, it works. I don't like adding the initData callback directly into the loadData method, though. What if I want to load data and do something to it before I use it? What if I have more methods to run when processing the data? Chaining this way would get unreadable pretty quickly, IMO.
What's a better, more modular way of doing this?
I'd prefer something that doesn't rely on jQuery (if there even is a magical jQuery way), for the sake of learning.
(Also, I'm sure I'm doing some other things horribly in this example. Please feel free to point out other mistakes I'm making, too. I'm going through Douglas Crockford's Javascript - The Good Parts, and even for a rank amateur, it's made a lot of sense, but I still haven't wrapped my head around it all)
Thanks!
I don't see a lot that should be different. I made an updated version of the fiddle here.
A few points I have changed though:
Use the var keyword for local variables e.g., self.
Don't add a temporary state as an object's state e.g., ajaxData, since you are likely to use it only once.
Encapsulate as much as possible: Instead of calling loadData with the object ajaxURL, let the object decide from which URL it should load its data.
One last remark: Don't try to meet requirements you don't have yet, even if they might come up in the future (I'm referring to your "What if...?" questions). If you try, you will most likely find out that you either don't need that functionality, or the requirements are slightly different from what you expected them to be in the past. If you have a new requirement, you can always refactor your model to meet them. So, design for change, but not for potential change.

Categories

Resources