Pass parameters to Javascript callback functions
This is what I have:
function populateElement(arg1) {
getData(arg1);
}
function getData(query) {
var url = "http://foo" + query + "&callback=processData";
// do stuff
}
function processData(results) {
callbackForGetData(results);
}
function callbackForGetData(result) {
// process data
}
I want to pass two more arguments to function populateElement like so:
function populateElement(arg1, arg2, arg3) {
getData(arg1);
}
And have the arg2, arg3 avai开发者_运维技巧lable in callbackForGetData
function callbackForGetData(result) {
// process data
// use arg2, arg3 here
}
How should I do this?
You can pass them on to the callback and access them in the arguments
array
function getData(result) {
//result === arg1
//arguments[0] === arg1
//arguments[1] === arg2
//arguments[2] === arg3
//and so on
}
getData(arg1, arg2, arg3);
Pass an object as a single paramater:
function populateElement(arg1, arg2, arg3) {
var params = {"arg1":arg1,"arg2":arg2,"arg3",arg3};
getData(params);
}
function getData(params) {
var query = params.arg1;
var url = "http://foo" + query + "&callback=processData";
// do stuff
}
Your are looking for a closure.
function getData(query) {
var url = "http://foo" + query + "&callback=processData";
// do stuff
//simulate the callback
processData("some results");
};
function populateElement(arg1, arg2, arg3) {
//Because we define processData here, we have a closure scope that
// lets us see all the arguments to populateElement
window.processData = function(results) {
console.log("ProcessData called with results: " + results +
", arg2: " + arg2 + ", arg3: " + arg3);
};
getData(arg1);
}
//Simulate the starting call
populateElement(4, 5, 6);
Here's a working jsfiddle.
Note this only supports a single (1) pending getData call. A more elaborate scheme would be necessary to support multiple concurrent pending getData calls. Each would need a unique callback closure name, which could be as simple as a trailing numeric serial number.
To pass more arguments, you can use call
or apply
.
function log(a, b, c) { console.log('A: ', a, ', b: ', b, ', c: ', c);}
log.call(window, 'first', 'second', 'third');
> A: first , b: second , c: third
log.apply(window, ['first', 'second', 'third'])
> A: first , b: second , c: third
But as Peter has suggested, you have some async stuff going on here and you want to save this on a closure, instead of passing extra arguments.
Have something like this, save your data in a closure:
function processData(results) {
// transform data
myModule.callbackForGetData(results);
}
window.myModule = {
populateElement: function(arg1, arg2, arg3) {
this.data = arguments;
this.getData(arg1);
},
getData: function(query) {
var script = document.createElement('script');
script.src = 'http://jsfiddle.net/echo/jsonp/?query=' + query + '&callback=processData';
document.getElementsByTagName('head')[0].appendChild(script)
},
callbackForGetData: function(result) {
// process data
console.log('Args: ', this.data, ', remote result: ', result);
}
}
// test it
myModule.populateElement(1, 2, 3)
> Args: [1, 2, 3] , remote result: Object {query: "1"}
精彩评论