I’m working on a project using Javascript/jQuery, and I am not primarily a Javascript/jQuery developer. I could really use a bit of advice from someone who is primarily a Javascript/jQuery developer. Is there anyone here who fits that bill, and would be willing to field a few questions?
I’m a JS dev and used Jquery for a long time. Might be a bit rusty but I may be able to help. What’s up?
Thanks in advance.
I have a function which does a whole lot of warehouse stock picking tasks. Essentially, before this function is called, the users pick stock off of pallets in the warehouse (so, like, I need 100 widgets on this order, I’m going to get 25 from pallet X, 25 from pallet Y, and 50 from pallet Z), and when that’s done this function then processes those picks, so that in the WMS system they’re ready to ship out.
When this function is called, it uses AJAX to hit a bunch of web services, with each web service performing a specific WMS task. These tasks have to execute synchronously, because the WMS requires step 1 to complete before step 2 starts, step 2 to complete before step 3 starts, and so on, and so forth. Each step is a different web service with a different AJAX call. Here is a sample of the AJAX call I’m making:
var ajaxMessage;
var ajaxDone;
$.ajax({
url: "/WmsHelper/SasPicking.ReservePicks.ashx?guid=" + ds_Guid + "&phid=" + headerId,
async: false,
success: function(result) { ajaxMessage = result; ajaxDone = true; },
error: function(result) { ajaxMessage = result; ajaxDone = true; }
});
while (ajaxDone == false) { }
I recognize that’s probably a HUGE hack, but it does work to keep the AJAX calls running synchronously. Anyway, between each of the AJAX calls, I am also updating a textarea on the form with some feedback, because these AJAX calls can take some time on larger datasets.
My problem is that the function containing all of these AJAX calls and other processing seems to be running asynchronously: when it executes, the document isn’t redrawn until the entire function completes, after a long pause while it processes, and then the textarea is suddenly filled with all the feedback messages instead of having them pop up during processing as they’re processed.
Like I said, I’m not primarily a Javascript/jQuery developer. If this were C#, it would be no issue. But it’s not. So, what do I have to do to make that function run in such a way that it will do one AJAX call, update the textarea, do the next AJAX call, update the textarea, all synchronously so that the user sees the updates in real time?
EDIT: I read something about “promises”, but I’m a bit fuzzy on the concept.
Don’t you mean the function is running synchronously, and you need it to run async?
With the exception of service workers, javascript in the browser always runs in one thread. So if you are blocking that thread to run sync, it won’t be able to update anything in the meantime.
You should make those ajax calls async.
It should go something like this:
var firstCall = $.ajax({...});
firstCall.then((result) => {
// do something with the result, update the ui
});
// if your second call should wait for the first one
var secondCall = firstCall.then(() => {
return $.ajax({...});
});
Not quite sure if that code is correct, I haven’t used jquery in years, I am an Angular developer these days, and always use Typescript.
You might be able to use async/await if you don’t have to support older browsers, but I also don’t know how nice the jquery promises will work with this.
Also, in my example I used arrow functions, be aware that those also have to be supported by the browser, and you should also be aware of the difference to “normal” functions (this is something else in both).
Yeah, I mostly work ReactJS/Typescript for the frontend and C# for the backend. There are so many things in C# that I wish were in Javascript. Typescript has brought a bunch of it to the JS world but I digress.
To your situation, however:
Long story short: even though you’re making a synchronous call using the async: false option, you’re still running on one single thread which means it’s not going to update until the entire function is complete.
There’s a couple of options for you. First, the most hacky solution, is to break up the functions into smaller parts and use “setTimeout()” to force updates as it goes along.
Something like:
function doLotsOfStuff() {
// do stuff
setTimeout(function() {
// do more stuff
setTimeout(function() {
// do even more stuff
}, 0);
}, 0);
}
The other option, less hacky and closer to the way things are done now, is to use Javascript’s Promise flow. Would look something like this:
function doLotsOfStuff() {
return new Promise(function(resolve, reject) {
$.ajax({
url: "/WmsHelper/SasPicking.ReservePicks.ashx?guid=" + ds_Guid + "&phid=" + headerId,
success: function(result) {
// update textarea
resolve();
},
error: function(result) {
// handle error
reject();
}
});
})
.then(function() {
return new Promise(function(resolve, reject) {
$.ajax({
url: "/WmsHelper/SasPicking.ReservePicks.ashx?guid=" + ds_Guid + "&phid=" + headerId,
success: function(result) {
// update textarea
resolve();
},
error: function(result) {
// handle error
reject();
}
});
});
})
.then(function() {
// do more stuff
});
}
doLotsOfStuff()
.then(function() {
// all done
})
.catch(function(error) {
// handle any errors that occurred during any of the above steps
});
Hopefully that gets you in the right direction. Also, bookmark this page: https://youmightnotneedjquery.com
It has a lot of great examples on how to do the most common jquery stuff in raw javascript. Makes the overall program lighter.
EDIT: for a quick and fantastic rundown on how Promises work, check this guy’s video out (as well as his whole channel. It’s fantastic.): https://www.youtube.com/watch?v=DHvZLI7Db8E