How does jQuery's synchronous AJAX request work? - asynchronous

Does jQuery.ajax({async: false}) still use the XMLHttpRequest object?
If so, how is the request synchronous?
Is there just some mechanism inside the function definition that allows the asynchronous request put out by the XHR to be wrapped in a synchronous wrapper?
I ask because I want to wrap asynchronous function calls into a synchronous wrapper.
EDIT:
I want to do this for dependencies. I need to not run anything more until all the external dependency scripts are loaded, however, I'd rather not load each of the files synchronously.
Basically, I want this:
require(['lib1.js','lib2.js'])
Library1Function();
Library2Function();
To load lib1 and lib2 at the same time, but block until both are loaded.
I know I could do this with a callback, however that doesn't work if the files I'm including also have dependencies included in the same way.
EDITx2
Reason why callbacks don't work:
# lib2.js
window.Library2Function = function(input) {
alert(input);
}
# lib1.js
require('lib2.js', function() {
window.Library1Function = function() {
window.Library2Function('Hi there');
}
});
# main.js
require('lib1.js', function() {
window.Library1Function();
});
The problem is that, in main.js, that callback will get sent off once lib1.js is loaded and run.
The problem is, Library2Function isn't actually defined until lib2.js is loaded, which happens after lib1.js is parsed.

Does jQuery.ajax({async: false}) still use the XMLHttpRequest object?
Yes.
XMLHttpRequest.prototype.open accepts async as its third parameter. If it's true (default), the request is asynchronous. Otherwise, it's synchronous.
I ask because I want to wrap asynchronous function calls into a synchronous wrapper.
Why do you want to do this? This will most likely result in more problems than it "fixes".

Related

Can someone explain how Meteor.defer() works?

So... Meteor.defer(function(){ // stuff }) isn't in the docs:
https://github.com/meteor/meteor/issues/2176
But this links seems to say that it's simply equivalent to
Meteor.setTimeout(function(){ // stuff }, 0);
If that's the case, how does this do, um, anything? It's basically saying "wait for 0 ms and then run the function".
So... it runs the function instantly.
What am I missing here? Is this kind of like Tracker.afterFlush or something? Does it somehow wait for "things" (what kind of things?) to finish before running?
I see Meteor.defer() a lot on SO being used as a bit of a hack on added helper methods to run after the dom is (somewhat) loaded - basically to get the same effect as running code inside of a Template.foo.rendered method.
However, the main (and best) use of Meteor.defer is to run a task asynchronously.
Let's say we have an app where we are sending an email. On the server, it may take several seconds for that to process inside of a meteor method, slowing down your application drastically. However, if you wrap that process in a Meteor.defer the email processing won't block execution, the email still sends (when it gets a chance, not instantly), but everything runs much faster, since the code that follows isn't waiting. There is a great example lesson about deferring execution at Bulletproof Meteor.
You can actually get the same effect with a setTimeout(f,0) - if you have a slow function, you could wrap it in the setTimeout and the rest of the code will complete, and 'defer' the slow process in the timeout, so although it doesn't seem like it, setTimeout(f,0) does actually have a pretty useful purpose!
To see an example of this in action, here's a fiddle, open the console and watch where 'foo' logs.
I faced some issue in my project because of asynchronous callback. Inside onCreated i was making a server Meteor.call and set the response inside reactiveVar. And i was doing something inside onRendered with that reactiveVar. Every time reactiveVar was showing undefined.
So i used Meteor.defer(function(){...}) inside onRendered and it sloved my issue.
Here is some demo with and without using Meteor.defer()
Template.myTemplate.onCreated(function () {
var instance = this;
instance.myTemplateModel = new ReactiveDict();
Meteor.call('all-user', function(err, res){
if(res){
console.log('inside callback');
instance.myTemplateModel.set('users', res);
}
});
});
Template.myTemplate.onRendered(function () {
var instance = this
console.log('rendered start');
Meteor.defer(function(){
console.log(instance.myTemplateModel.get('users'));
});
console.log('render end');
});
Console:
/*Without Meteor.defer()*/ | /*With Meteor.defer()*/
render start | inside callback
undefined | render start
render end | render end
inside callback | [Object, Object, Object]

Meteor wrapAsync syntax

How do I use the Meteor wrapAsync?
Below is what I am trying to do
if (tempTreatment.groupId === undefined) {
// create new group
Meteor.wrapAsync(Meteor.call('createTreatmentGroup', salon, tempTreatment.groupName, tempTreatment.groupName));
// get group id
var getGroup = Meteor.wrapAsync(Meteor.call('getTreatmentGroup', salon, tempTreatment.groupName));
console.log(getGroup);
tempTreatment.groupId = getGroup._id;
}
I want to run these two Meteor.callfunctions synchronosly but I get undefined on console.log(getGroup); which shuold just return an object.
Meteor.wrapAsync is a server-side API designed to wrap Node.js asynchronous functions requiring a callback as last argument, to make them appear synchronous through the use of Futures, a Fibers sub-library. (more on this here : https://www.discovermeteor.com/blog/wrapping-npm-packages/)
It is not intended to be used client-side to turn asynchronous Meteor.call into a synchronous call because on the browser, Remote Method Invokation calls are ALWAYS asynchronous.
Long story short, you simply cannot achieve what you're trying to do, you have to use callbacks and nest your second method call inside the success callback of your first method call.

SignalR .Net client - how to invoke synchronously and asynchronously

I'm learning SignalR using the .Net client (not javascript), and was hoping for some clarification on how to invoke hub proxy methods in a synchronous or asynchronous manner.
Method with no return value
So far I've been doing something like this:-
myHubProxy.Invoke("DoSomething");
I've found this to be asynchronous, which is fine as it's effectively "fire-and-forget" and doesn't need to wait for a return value. A couple of questions though:-
Are there any implications with wrapping the Invoke in a try..catch block, particularly with it being asynchronous? I might want to know if the call failed.
Are there any scenarios where you would want to call a method that doesn't return a value synchronously? I've seen the .Wait() method mentioned, but I can't think why you would want to do this.
Method with return value
So far I've been using the Result property, e.g.:-
var returnValue = myHubProxy.Invoke<string>("DoSomething").Result;
Console.WriteLine(returnValue);
I'm assuming this works synchronously - after all, it couldn't proceed to the next line until a result had been returned. But how do I invoke such a method asynchronously? Is it possible to specify a callback method, or should I really be using async/await these days (something I confess to still not learning about)?
If you want to write asynchronous code, then you should use async/await. I have an intro on my blog with a number of followup resources at the end.
When you start an asynchronous operation (e.g., Invoke), then you get a task back. The Task type is used for asynchronous operations without a return value, and Task<T> is used for asynchronous operations with a return value. These task types can indicate to your code when the operation completes and whether it completed successfully or with error.
Although you can use Task.Wait and Task<T>.Result, I don't recommend them. For one, they wrap any exceptions in an AggregateException, which make your error handling code more cumbersome. It's far easier to use await, which does not do this wrapping. Similarly, you can register a callback using ContinueWith, but I don't recommend it; you need to understand a lot about task schedulers and whatnot to use it correctly. It's far easier to use await, which does the (most likely) correct thing by default.
The .Result property returns a async Task, so the server requests is still performed async.
There is not reason to hold up a thread for the duration of the call thats why you use async.
If you fire the call on the GUI thread its even more important todo it async because otherwise the GUI will not respond while the call is done
1) Yuo need to use the await keyword if you want try catch blocks to actually catch server faults. Like
try
{
var foo = await proxy.Invoke<string>("Bar");
}
catch (Exception ex)
{
//act on error
}
2) I think you ment to ask if its any reason to call it async? And yes like I said, you do not want to block any threads while the request is being made

How to delay AngularJS App Initialization?

I have some data that is being processed asynchronously in the background and want to delay the initialization of the entire AngularJS application until this finished.
BackgroundData.initialized is a Q promise, so something like this:
BackgroundData.initialized.then(AngularDoYoStuff)
The problem I run into is the home page's controller starts its initialization procedure, hits BackgroundData and either it has the wrong/no data.
What function can I wrap Angular's initialization in so, instead of just dom-ready, it waits for both dom-ready and BackgroundData.initialization?
UPDATE
I have gotten closer with the documentation on manual bootstrapping:
angular.element(document).ready ->
setupGA()
window.BackgroundData = new DataMachine()
BackgroundData.initialized.then ->
angular.bootstrap(document)
But when the controller files load (after this file), they are still getting initialized before BackgroundData is defined
UPDATE 2
Removing the ng-app directive in the HTML seems to have fixed the problem (since that was telling Angular to auto-init) but now it just ignores all of my angular.module calls
The problem was that I had left the ng-app directive in the html tag, which tells Angular to auto-initialize that scope. Removing it allowed my manual initialization to run correctly.
as Chris mentioned, it can be done with angular.bootstrap and not mentioning the ng-app:
<div id="appArea" ng-controller="someCtrl">
{{name}}
</div>
<script>
angular.module('someApp', [])
.controller('someCtrl', function($scope) {
$scope.name = "test name";
})
setTimeout(function() {
angular.bootstrap(document, ['someApp']);
}, 2000);
</script>
One way to approach this if you are using routes in your app is to have the app initialize but wait on defining routes until the data is available.
I.e. provide a user-friendly 'loading' message, and then load functionality after.
You are able to inject $route where required, and then call something like:
$route.routes["/RouteName/:param"] = {templateUrl:"template.html", reloadOnSearch:true, controller:"ControllerName"};
After that, call $route.reload() or $rootScope.apply() to refresh.
More information at https://groups.google.com/forum/?fromgroups=#!msg/angular/AokZpUhZ6mw/x2kPIN2VAC0J

Handle multiple requests with ICallbackEventHandler

Is there any way to make multiple requests to the callback function in asp.net when using the ICallbackEventHandler? I need the results for each result, however, when I iterate through and call the function, I get the result only for the last call. Any way to make it return a result for each call?
This is what I am passing in via javascript:
function NoPostback() {
$(".spans").each(function(index, item) {
CallServer($(item).attr("myattr"));
});
}
In this, myattr is a custom attribute that holds a value (1..10). What I want returned is something like ('you said: ' + id) to be returned for each of the calls, so that I can go ahead and place them in the appropriate holders.
However, only one item is returned which is the final call made. For instance if there are 4 items, it returns only ('you said: 4').
Any idea on how to have all of them returned?
Thanks in advance.
Most Javascript AJAX frameworks either abort any subsequent requests if one is in progress, or they ignore previous requests and only handle the latest. The AJAX request itself will pass through the browser's XmlHttpRequest object, but the rest of the javascript code is running within the pages thread. Currently, there is no concurrent programming with javascript (however this is slated to change.)

Resources