Reputation: 1142
I am using a JavaScript API of some software. In software there are Solutions and they contain Worklists.
For each Solution I want to list Worklists.
solutions = obtainSolutionsformAPI();
for (i=0,i<solutions.length,i++){
sol=solutions[i];
sol.obtainWorklists(callbackFunction);
}
the callbackFunction is called by software and the array of worklists is passed as the argument.
function callbackFunction(arrayOfWorkLists){
for (j=0,j<arrayOfWorkLists.length,j++){
wl=arrayOfWorkLists[j];
console.log(wl);
}
}
now in console.log I would like to also print out the i
variable (the number of solution) together witch each worklist, but how do I get the i
inside callback function, when I am not the one who is calling it? I suspect I need to modify the callback function each time before I pass it to sol.obtainWorklists(callbackFunction);
What is the correct way of doing this?
Edit: I do not want the function defintions to be nested (one inside other), because I have multiple nestings like this one and it would be quite unreadable. So I do not want this:
sol.obtainWorklists(function callbackFunction(arrayOfWorkLists){...});
Upvotes: 0
Views: 70
Reputation: 1075159
You can use a builder function:
sol.obtainWorklists(buildCallback(i, callbackFunction));
...where buildCallback
looks like this:
function buildCallback(index, func) {
return function() {
var args = [index];
args.push.apply(args, arguments);
func.apply(this, args);
};
}
Complete example below
Then in your callback, expect the i
value as the first argument with the arguments that obtainWorklists
normally provides following it.
How that works:
buildCallback
, you pass in the i
value and the callback you want called.buildCallback
returns a new function which has that information bound to it (it's a closure over the index
and func
arguments in the call to buildCallback
).obtainWorklists
calls the function buildCallback
created, we create an array with the i
value (index
) followed by the arguments that were received from obtainWorklists
.this
value that the function was called with, and the args
array; your callback will see the entries in args
as discrete arguments.If you don't care about the this
value in your callback, you can use ES5's Function#bind
instead:
sol.obtainWorklists(callbackFunction.bind(null, i));
That does much the same thing, but doesn't preserve the this
used to call it.
Complete example for builder function (live copy):
// obtainWorklists stand-in
function obtainWorklists(func) {
setTimeout(function() {
// Just call it with a random number
func(rand(100, 200));
}, rand(100, 500));
}
// Code to get worklists
var i;
for (i = 0; i < 10; ++i) {
obtainWorklists(buildCallback(i, callback));
}
function buildCallback(index, func) {
return function() {
var args = [index];
args.push.apply(args, arguments);
func.apply(this, args);
};
}
// Your callback
function callback(index, value) {
display("Index is " + index + ", value is " + value);
}
// ========= Utility functions
function rand(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
Complete example for Function#bind
(live copy):
// obtainWorklists stand-in
function obtainWorklists(func) {
setTimeout(function() {
// Just call it with a random number
func(rand(100, 200));
}, rand(100, 500));
}
// Code to get worklists
var i;
for (i = 0; i < 10; ++i) {
obtainWorklists(callback.bind(null, i));
}
// Your callback
function callback(index, value) {
display("Index is " + index + ", value is " + value);
}
// ========= Utility functions
function rand(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
Upvotes: 2
Reputation: 781974
You need to use a closure:
solutions = obtainSolutionsformAPI();
for (i=0,i<solutions.length,i++){
(function(innerI) {
sol=solutions[innerI];
sol.obtainWorklists(function(worklists) {
callbackFunction(worklists, innerI);
}
})(i);
}
function callbackFunction(arrayOfWorkLists, i){
console.log(i);
for (j=0,j<arrayOfWorkLists.length,j++){
wl=arrayOfWorkLists[j];
console.log(wl);
}
}
Upvotes: 2