Chaining asynchronous methods in JavaScript - javascript

I'd like to do something like this:
var res = myAjax.post();
myAjax is basically my own ajax wrapper (asynchroneous). I don't necessary need the chaining, but i'd like to be able to do the call like shown above. I'd like a callback to be handled by the object itself. I've read about asynchroneous method queues, but, honestly, couldn't fully understand it. I know i could use a synchroneous ajax call, but it should be possible to do it asynchroneously as well if i understand it correctly. Any help is very appreciated. Thank you.

I've done a demo here that might be something along the lines of what you mean...
In that demo, there are two types of objects: MyAjax which has the 'post' method as above, and a MyRes object with a getData method that will return null until the async call has successfully completed. After it has completed, it will return the data fetched from the ajax call.
In the demo, I have a function checking for the response every second, but the post method also handles a callback which allows you to be notified when the ajax call has completed successfully.
I don't know why you'd want to do it this way, but it is doable.

Related

call functions passed as props one after another in react

I have a component in React that receives 2 functions as props, they work pretty well. However, I need to call them one after another, as promises. By now I am calling them as:
this.props.function1();
this.props.functions2();
But they are called in parallel, I tried:
let whenfirst =this.props.function1();
whenfirst.then(this.props.function2());
But then I get: TypeError: whenfirst is undefined
I really cannot make modifications over function1, so how is the easy way to execute the function2 after function1 is completed?
EDIT: Sorry, I missed the crucial part where you said you can't change function1. Ignore the rest.
So I'm guessing function1 looks something like this
function function1() {
// make the POST call
someAJAXLibrary.post('someUrl', maybePostData);
// Do nothing.. post is doing its work and maybe
// you didn't care about the return
}
Which means you can't know when the POST call is done. But the library POST call probably does return a Promise (that's pretty standard), you just don't use it.
So instead do
function function1() {
return someAJAXLibrary.post('someUrl', maybePostData);
}
Now you can use it like you first thought, in your component.
let whenfirst = this.props.function1();
whenfirst
.then(useMeOrNot => this.props.function2());

setting a property on a model in an ajax callback

I'm trying to set a property on a model in an ajax callback that I can use later, and I'm not sure if I can do this.
var self = this;
$.ajax {
self.views.someProperty = // something i get back from the server
}
then later do something with this.views.someProperty. Currently I get this.views.someProperty is undefined. I was wondering if I'm going about this correctly or not.
First off, you code snippet doesn't really make sense. $.ajax() calls a callback function when it's done with the result it retrieved and your code snippet doesn't show that proper form.
Assuming you are properly specifying a callback function, here are some other possible issues:
Timing - the result of the ajax call will not be available until AFTER the completion callback is called. This is some time later after $.ajax() is called. The result will not be available in code that executes right after $.ajax().
Does self.views exist already? If not, then setting self.views.someProperty would cause an error and would not work.
When you access this.views.someProperty later, you obviously need to make sure that this is the right value.
You can check the first item by putting a console.log("ajax call finished") in your ajax completion callback and a console.log("accessing someProperty") right before you try to access the value and then verify that the ajax completion is called before you try to access it.
You can check items 2 and 3 by examining the data in the debugger to make sure everything is what you intend.

Possible Javascript scope issue

I'm sort of a noob with this so please forgive me :)
I can't get this one part of the function to update the variable. Could anyone possibly take a look a see what I'm doing wrong?
http://pastie.org/private/zfnv8v2astglabluo89ta
From line 142 thru 172 I'm not getting any results in the end. I've tested inside that function to make sure it is actually returning data, but the "body" variable is passing back up after line 172. So if I look at my generated HTML on the page, it simply looks the function skips from 140 to 174.
Thanks for any feedback!!
Your $.get is asynchronous. That means it will finish sometime AFTER the rest of the code, thus you won't see it's effect on the body variable inside that function. Instead, it's success callback function will be called long after this function has already finished.
To chain multiple asynchronous ajax calls like you have here, you can't just use normal sequential programming because asynchronous ajax calls aren't sequential. The network request is sent, then your javascript continues executing and SOMETIME LATER when the response arrives, the success handler is called and is executed.
To run sequential ajax calls like you have, you have to nest the work inside the success handler so that the ONLY code that uses the response is actually in the success handler. In pseudo-code, it looks like this:
$.get(..., function(data) {
// operate on the results only in here
// a second ajax function that uses the data from the first
// or adds onto the data from the first
$.get(..., function(data) {
// now finally, you have all the data
// so you can continue on with your logic here
});
// DO NOT PUT ANYTHING HERE that uses the responses from the ajax calls
// because that data will not yet be available here
});
You cannot do what you're doing which is like this:
var myVariable;
$.get(..., function(data) {
// add something to myVariable
});
$.get(..., function(data) {
// add something to myVariable
});
$.get(..., function(data) {
// add something to myVariable
});
// do something with myVariable
None of those ajax calls will have completed before the end of your function. You have to follow a design pattern like in my first example.
For more advanced tools, one can always use jQuery deferreds which are just a different way of defining code to run after an ajax call is done. It looks a little more like sequential programming even though it's really just scheduling code to run the same way my first code example does.
Function 8 will be invoke after line 174-180. You must put code from 174-180 line to the end of function

Implement a callback with a function that doesn't accept a callback?

This is a newbie question: I have a pre-existing function that I would like to have call another function when it is finished, however, it does not accept a callback nor of course call one. I can modify this code to accept and call a function however this got me thinking about whether JavaScript supports doing this ... I would think it does but I've never had reason to find this out, I'm assuming it's necessary when working with libraries where we cannot change the code to our liking. Thanks.
The only time you need a callback is when you are doing something asynchronous, such as:
making an HTTP request (and waiting for a response)
animating something, one frame every time period until it is done
waiting for the user to click a button
All of these are considered "done" when something happens, but there is no generic way to determine when the something has happened. You need something custom for each one.
If you aren't waiting for something, then you can just call one function after the other (foo();bar();) and not need to fiddle around with callbacks.
So…
It might be possible to do what you want, but we can't tell you a generic way to achieve it.
This is a bit of a hack, and i'm sure there's tidier ways to do this with polymorphism, but you can treat the function as a variable and re-assign it somewhat:
Say you start with this function:
function originalFunctionName()
{
// do something
}
you can assign the existing function to a new name:
var backupOfOriginal = originalFunction;
then you can define a new function over the original name:
var originalFunctionName = function()
{
// do something else
// call backup function
backupOfOriginal();
}
then if you call the original function name:
originalFunctionName();
all the code will execute.
You can always create a new function which calls that function and provides you with opportunities to do something else before and after it is called. Underscore.js provides .wrap() to do exactly that sort of thing and return you a function you can call instead of the first function.
That just gives you a new function to call instead of your original function, if you want every spot that called the original function to get the new behavior instead, you could take advantage of JavaScript's prototypal inheritance to replace the original function with your new version of it.
Create a wrapper function that calls the original function, then one you pass in.
If the original function is an Ajax call and you're trying to replace one of its handlers, that's a different issue, though you might be able to use jQuery's $.when(original).then(function () { ... }) depending on your actual needs.

Javascript: Trigger action on function exit

Is there a way to listen for a javascript function to exit? A trigger that could be setup when a function has completed?
I am attempting to use a user interface obfuscation technique (BlockUI) while an AJAX object is retrieving data from the DB, but the function doesn't necessarily execute last, even if you put it at the end of the function call.
Example:
function doStuff() {
blockUI();
ajaxCall();
unblockUI();
};
Is there a way for doStuff to listen for ajaxCall to complete, before firing the unBlockUI? As it is, it processes the function linearly, calling each object in order, then a separate thread is spawned to complete each one. So, though my AJAX call might take 10-15 seconds to complete, I am only blocking the user for just a split-second, due to the linear execution of the function.
There are less elegant ways around this...putting a loop to end only when a return value set by the AJAX function is set to true, or something of that nature. But that seems unnecessarily complicated and inefficient.
However you're accomplishing your Ajax routines, what you need is a "callback" function that will run once it's complete:
function ajaxCall(callback){
//do ajax stuff...
callback();
}
Then:
function doStuff(){
blockUI();
ajaxCall(unblockUI);
}
Your AJAX call should specify a callback function. You can call the unblockUI from within the callback.
SAJAX is a simple AJAX library that has more help on how to do AJAX calls.
There's also another post that describes what you're looking for.
You can do a synchronous xhr. This would cause the entire UI block for the duration of the call (no matter how long it might take).
You need to redesign your program flow to be compatible with asynchronus flow, like specifying a callback function to be called after the response is processed. Check out how Prototype or JQuery or ... accomplishes this.
The answer is simple, you have to call unblockUI() when your ajax request returns the result, using jQuery you can do it like this:
function doStuff(){
blockUI();
jQuery.ajax({
url: "example.com",
type: "POST", //you can use GET or POST
success: function(){
unblockUI();
}
});
}
It sounds to me that you want the user to wait while info is being fetched from the db. What I do when I make an Ajax call for some info from the database is to display an animated gif that says "getting it..." - it flashes continually until the info is retrieved and displayed in the webpage. When the info is displayed, the animated gif is turned off/hidden and the focus is moved to the new info being displayed. The animated gif lets the user know that something is happening.

Categories

Resources