This question already has answers here:
Why does JQuery.getJSON() have a success and a done function?
(2 answers)
Closed 5 years ago.
I would like to know if there are any conceptual differences between these two codes:
Code 1:
$(function(){
var url = "url";
$.getJSON(url, function(data){
console.log(data);
})
});
Code 2:
$(function(){
var url = "url";
$.getJSON(url).done(function(data){
console.log(data);
})
});
In which situation the $.getJson().done() method is most relevant ?
The First one uses a callback function as a second param. This allows you to execute code after the function is completed. Note, you are in a separate function.
The Second also uses a callback function as a promise but it is working different under the hood.
// version one
setTimeout(function() {
doStuff1();
doStuff2();
}, 1000)
// version one - callback
function doStuff1() {
doSomething1("value", function(responce) {
console.log(responce);
});
};
function doSomething1(v, cb) {
if (typeof v === "string") {
cb(true);
} else {
cb(false);
}
return false;
}
// note the function will always return false but the callback gets the value you want
// version 2, class with promise callback
// look at the class function and see how it works slightly differently
function doStuff2() {
var $ = new doSomething2();
$.Something("value").done(function(resp) {
console.log(resp)
});
};
class doSomething2 {
constructor() {
this.v = false;
}
Something(val) {
if (typeof val === "string") {
this.v = true;
} else {
this.v = false;
}
return this;
}
done(cb) {
return cb(this.v);
}
}
Related
I have a section in my code that looks like this
var locationDefer = $.Deferred();
if (saSel.Company === -1) {
database.getAllLocations().then(function (result) {
var locations = JSON.parse(result.d);
locationDefer.resolve(locations);
});
} else {
database.getLocationsForCompany(saSel.Company).then(function (result) {
var locations = JSON.parse(result.d);
locationDefer.resolve(locations);
});
}
However, since it is basically the same thing twice, just with a different ajax call - is there any way to either have the anonymous function part
function (result) {
var locations = JSON.parse(result.d);
locationDefer.resolve(locations);
})
declared as a real function and then just called in the .then() clause, or can I somehow provide the to-be-called-function of the database object?
For the latter, I had something in my mind that could look like this, but I have no clue how to do the last line.
if(saSel.Company === -1) {
fun = 'getAllLocations';
arg = null;
} else {
fun = 'getLocationsForCompany';
arg = saSel.Company;
}
// database.fun(arg).then(function (result) {...});
You can define a function and pass its reference as success callback handler
//Define the function handler
function resultHandler(result) {
var locations = JSON.parse(result.d);
locationDefer.resolve(locations);
}
if (saSel.Company === -1) {
fun = 'getAllLocations';
arg = null;
} else {
fun = 'getLocationsForCompany';
arg = saSel.Company;
}
//Invoke the method using Bracket notation
//And, pass the success handler as reference
database[fun](arg).then(resultHandler);
Additionally, as getLocationsForCompany() and getAllLocations() returns a promise, you shouldn't use $.Deferred() directly return Promise
return database[fun](arg);
This question already has answers here:
Function in JavaScript that can be called only once
(32 answers)
Closed 6 years ago.
Execute function only one time in Javascript, no matter how many times it has been called.
I write the following code, but does not working.
var counter = 0;
if(n.data === YT.PlayerState.BUFFERING) {
setTimeout(function() {
if(counter===0) {
r.frontPlayer.seekTo(10);
counter++;
}}, 2000);
}
Try not to use timeouts, they invite misery and suffering. This is a simple example, I use jquery for attaching the events but the function is independent of jquery. The key thing is using the object, the anonymous function in this case, to track state.
<button id="testButton">
test
</button>
$("#testButton").click(function() {
if (null == this.ran) {
console.log("do something");
this.ran = true;
}
})
Take a look at underscore or lodash's _.once function:
var fn = _.once(function() {
console.log('this will only run once');
});
Or writing it yourself:
var fn = (function() {
var called = false;
var ret;
return function() {
if (called) return ret;
called = true;
// do stuff
// ..
ret = 'some return value';
return ret;
};
})();
I have a JavaScript class that is meant to help deal with promises. First you add functions to an array, then it executes them pops them and calls itself to do the next one. At the end of the array it resolves that promise. My hope was to then propagate the resolution all the way up the stack of recursive calls. This will allow you to force multiple asynchronous functions to run sequentially using a simple set of commands. furthermore employ logic to modify the flow of the ansync functions.
function Sequencer() {
this.functionSequence = [];
this.addFunction = function (func) {
this.functionSequence.push(func);
}
this.getFunctionSequence = function () {
return functionSequence;
}
this.executeAll = function () {
var functionList = this.functionSequence;
var deferred = $q.defer();
if (functionList.length > 0) {
functionList[0]().then(function (result) {
if (result) {
functionList.splice(0, 1);
executeAll().then(function (resultInner) {
if (resultInner == true) {
deferred.resolve(true);
} else {
deferred.resolve(false);
}
});
} else {
functionList = [];
deferred.resolve(false);
}
});
} else {
deferred.resolve(true);
}
return deferred.promise;
}
}
I am getting ReferenceError: 'executeAll' is undefined
in this script, on the recursive call line "executeAll' just after the splice
the first function in the array is being executed(I was testing it with a modal pop up) and when it resolves it hits the splice, then it throws the error right on the executeAll line. Am I defining the function incorrectly? Am I calling it correctly as a recursive function?
use this.executeAll - assuming this will be correct, which it wont, so you'll need to account for that as well ... something like var self = this at the top of executeAll, then call self.executeAll
this.executeAll = function() {
var functionList = this.functionSequence;
var deferred = $q.defer();
var self = this; // save reference to this
if (functionList.length > 0) {
functionList[0]().then(function(result) {
if (result) {
functionList.splice(0, 1);
// need to use self here because "this" is not the "this" we want
self.executeAll().then(function(resultInner) {
if (resultInner == true) {
deferred.resolve(true);
} else {
deferred.resolve(false);
}
});
} else {
functionList = [];
deferred.resolve(false);
}
});
} else {
deferred.resolve(true);
}
return deferred.promise;
};
The reason this is not the this you "want" is due to how this works in javascript - there is plenty on info on stack exchange about using this - I'll find and link a good answer shortly
I offer this alternative code
this.executeAll = function() {
return this.functionSequence.reduce(function(promise, item) {
return promise.then(function(result) {
if (result) {
return item();
}
else {
throw "Fail"; // throw so we stop the chain
}
});
}, Promise.resolve(true))
.then(function(result) {
this.functionSequence = []; // clear out the added functions
return true; // fulfilled value is true as per original code
}.bind(this), function(err) {
this.functionSequence = []; // clear out the added functions
if (err == "Fail") {
return false; // convert the "Fail" to a fullfilled value of false as per original code
}
else {
throw err; // any other error - re-throw the error
}
}.bind(this))
};
This question already has answers here:
Jquery .each() - return value undefined
(3 answers)
Closed 9 years ago.
Why the does following Javascript function return "undefined" in alert.
here is the snipptet
var tests = validateUserSelectedExperType(userSelectedOptioName);
alert(tests);
Code
function validateUserSelectedExperType(inp) {
$.each(splitter.getFirstPaneContent(), function (index, item) {
var splitterinner = splitter.getFirstPaneContent()[index];
var getLabel = splitterinner.getFirstPaneContent()[0];
if (getLabel.getText() == inp) {
return true;
} else {
return false;
}
});
}
You're returning from the nested function, not from the validateUserSelectedExperType function. Set a boolean and update that value instead. At the end, return it:
function validateUserSelectedExperType(inp) {
var flag = false;
$.each(/* ... */, function (index, item) {
// ...
if (getLabel.getText() == inp) {
flag = true;
return false;
}
});
return flag;
}
That's because your return statements are within $.each() anonymous function. Returning falsefrom that function will stop the each loop.
You have to return something for the main function (I can't understand your code logic, so I can't help you in that).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to return the response from an AJAX call from a function?
on my App namespace i've just defined a function:
version 1
window.App = {
isLogged: function () {
$.get('/user/isLogged', function (data) {
if (data == 'true') {
return true;
}
return false;
});
}
};
version 2
window.App = {
isLogged: function () {
var test = $.get('/user/isLogged');
console.log(test.responseText);
}
};
On version 1 when i try the function on firebug 'App.isLogged()' i got a nice undefined :S
On version 2 when i try the function on firebug, the responseText seems to be undefined :stuck:
I'm pretty new about javascript, and maybe a scope issue...
The goal of my function is clear i think, there's a better way to achieve this?
on first version
$.get is asynchronous that's why you don't get a return value
on second version
$.get returns deferred object that doesn't have responseText field
window.App = {
isLogged: function () {
var dfd = $.Deferred();
$.get('/user/isLogged', function (data) {
if (data == 'true') {
return dfd.resolve();
}
return dfd.reject();
});
return dfd.promise();
}
};
$.when(App.isLogged()).then(function() {
//your code
}).fail(function() {
//fail code
});