I am in the process of using the Splunk Javascript API to gain access to some of its functionality, but I'm having trouble understanding JavaScript concepts behind callbacks.
An example from the docs:
var http = new splunkjs.ProxyHttp("/proxy");
var service = new splunkjs.Service(http, {
username: username,
password: password,
scheme: scheme,
host: host,
port: port,
version: version
});
Async.chain([
// First, we log in
function(done) {
service.login(done);
},
// Perform the search
function(success, done) {
if (!success) {
done("Error logging in");
}
service.search("search index=_internal | head 3", {}, done);
},
// Wait until the job is done
function(job, done) {
Async.whilst(
// Loop until it is done
function() { return !job.properties().isDone; },
// Refresh the job on every iteration, but sleep for 1 second
function(iterationDone) {
Async.sleep(1000, function() {
// Refresh the job and note how many events we've looked at so far
job.fetch(function(err) {
console.log("-- fetching, " + (job.properties().eventCount || 0) + " events so far");
iterationDone();
});
});
},
// When we're done, just pass the job forward
function(err) {
console.log("-- job done --");
done(err, job);
}
);
},
// Print out the statistics and get the results
function(job, done) {
// Print out the statics
console.log("Job Statistics: ");
console.log(" Event Count: " + job.properties().eventCount);
console.log(" Disk Usage: " + job.properties().diskUsage + " bytes");
console.log(" Priority: " + job.properties().priority);
// Ask the server for the results
job.results({}, done);
},
// Print the raw results out
function(results, job, done) {
// Find the index of the fields we want
var rawIndex = utils.indexOf(results.fields, "_raw");
var sourcetypeIndex = utils.indexOf(results.fields, "sourcetype");
var userIndex = utils.indexOf(results.fields, "user");
// Print out each result and the key-value pairs we want
console.log("Results: ");
for(var i = 0; i < results.rows.length; i++) {
console.log(" Result " + i + ": ");
console.log(" sourcetype: " + results.rows[i][sourcetypeIndex]);
console.log(" user: " + results.rows[i][userIndex]);
console.log(" _raw: " + results.rows[i][rawIndex]);
}
// Once we're done, cancel the job.
job.cancel(done);
}
],
function(err) {
callback(err);
}
);
Async.chain is defined here as being root.chain = function(tasks, callback)
. My understanding is that there are 5 functions in the tasks array which are executed one after the other, and pass the results from one to the other.
However I do not understand how and where "done", "success","job" and "results" are defined, or how it is that they are used as arguments within the body of their functions?
function(success, done) {
if (!success) {
done("Error logging in");
}
service.search("search index=_internal | head 3", {}, done);
}
here, how is it testing against success, and passing a string to done()?
and how does the two functions
function(job, done) {// Print out the statics ..}
&
function(results, job, done) { .. }
pass the results data from the first function to the second?
Apologies for the long question.
In Javascript, functions create new scope. That means it does not matter what the passed arguments were named before they were passed to the function.
var awesomeName = 'bob';
hi(awesomeName);
// name === undefined
function hi(name) {
// name === 'bob';
console.log('hi', name); // Outputs: 'hi bob' in console
}
// name === undefined
As you said, each task calls the next task as a callback. The last argument is always the next task function/callback . That means that Async.chain
probably automagically adds the callbacks to the end of the arguments before calling each task function. done
is just a conventional name to assign to the callback. Similarly, the other arguments are just descriptive names for the arguments passed by the previous task. In order to see why they are named that way, you should look at the function that is calling the callback.
For example:
service.login(done)
probably has some kind of code in it that does something like this:
login: function(callback) {
var successful;
// Do Login logic here and assign true/false to successful
callback(successful);
}
The callback is the next task in the chain and has two arguments, success
and done
. success
is just the first argument that login
passed to it. Async.chain
always passes another argument as the last argument: the next task function, which is just assigned the name done
by convention. You could name it whatever you want within each function, as long as you refer to it as the same name within the function.
function cb(success, fuzzyCallback) {
if (!success) {
fuzzyCallback('Error!');
}
fuzzyCallback(null);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.