32
loading...
This website collects cookies to deliver better user experience
a
followed by b
) in a synchronous program, b
cannot start running until a
has ended.a
followed by b
), where a
schedules a job to run in the future but b
executes before that task completes.setTimeout
function is probably the simplest way to asynchronously schedule code to run in the future:// Say "Hi."
console.log("Hi.");
// Say "Good afternoon" 5 seconds from now.
setTimeout(function() {
console.log("Good afternoon");
}, 5000);
// Say "Hi again!"
console.log("Hi again!");
setTimeout
does not pause the execution of the code. It only schedules something to happen in the future, and then immediately continues to the next line.function getData() {
var result;
$.get("process.php", function(response) {
result = response;
});
return result;
}
var result = getData();
console.log("The result is: " + result);
setTimeout
in the example above, $.get
does not pause the execution of the code, it just schedules some code to run once the server responds. That means the return result
; line will run before result = response
, so the code above will always print "The data is: undefined".callback function
callback function
that we pass into an asynchronous function, which will be called once the task is completed.var result = getData();
console.log("The result is: " + result);
getData
:getData(function(result) {
console.log("The result is: " + result);
});
getData
know that we're passing in a function? How does it get called, and how is the result
parameter populated? Right now, none of this is happening; we need to change the getData
function as well, so it will know that a callback function is its parameter.function getData(callback) {
$.get("process.php", function(response) {
callback(response);
});
}
$.get
before, perhaps without realizing what it was. We also passed in a callback to the setTimeout(callback, delay)
function in the first example.$.get
already accepts a callback, we don't need to manually create another one in getData
, we can just directly pass in the callback that we were given:function getData(callback) {
$.get("process.php", callback);
}
window.onclick
), setTimeout
, and setInterval
, or AJAX requests
.setTimeout
, you could create a synchronous function to do nothing for a certain amount of time:function pause(duration) {
let start = new Date().getTime();
while (new Date().getTime() - start < duration);
}
pause
function above or a synchronous AJAX call, then the user will not be able to do anything while they are running.for (var i = 1; i <= 3; i++) {
setTimeout(function() {
console.log(i + " second(s) elapsed");
}, i * 1000);
}
1 second(s) elapsed.
2 second(s) elapsed.
3 second(s) elapsed.
4 second(s) elapsed.
4 second(s) elapsed.
4 second(s) elapsed.
console.log(i + " second(s) elapsed");
is in the callback of an asynchronous function. By the time it runs, the for-loop will have already terminated and the variable i
will be equal to 4
.setTimeout
in a closure, which will create a new scope with a different i
in each iteration:for (var i = 1; i <= 3; i++) {
(function(i) {
setTimeout(function() {
console.log(i + " second(s) elapsed");
}, i * 1000);
})(i);
}
let
instead of var
, since let
creates a new scope for i
in each iteration:for (let i = 1; i <= 3; i++) {
setTimeout(function() {
console.log(i + " second(s) elapsed");
}, i * 1000);
}
var text = readFile(fileName),
tokens = tokenize(text),
parseTree = parse(tokens),
optimizedTree = optimize(parseTree),
output = evaluate(optimizedTree);
console.log(output);
readFile(fileName, function(text) {
tokenize(text, function(tokens) {
parse(tokens, function(parseTree) {
optimize(parseTree, function(optimizedTree) {
evaluate(optimizedTree, function(output) {
console.log(output);
});
});
});
});
});
function readFinish(text) {
tokenize(text, tokenizeFinish);
}
function tokenizeFinish(tokens) {
parse(tokens, parseFinish);
}
function parseFinish(parseTree) {
optimize(parseTree, optimizeFinish);
}
function optimizeFinish(optimizedTree) {
evalutate(optimizedTree, evaluateFinish);
}
function evaluateFinish(output) {
console.log(output);
}
readFile(fileName, readFinish);
function performTasks(input, tasks) {
if (tasks.length === 1) return tasks[0](input);
tasks[0](input, function(output) {
performTasks(output, tasks.slice(1)); //Performs the tasks in the 'tasks[]' array
});
}
performTasks(fileName, [
readFile,
token,
parse,
optimize,
evaluate,
function(output) {
console.log(output);
}
]);
getData
function that makes an AJAX request and uses a callback in the usual way:function getData(options, callback) {
$.get("process.php", options, function(response) {
callback(null, JSON.parse(response));
}, function() {
callback(new Error("AJAX request failed!"));
});
}
// usage
getData({name: "John"}, function(err, data) {
if(err) {
console.log("Error! " + err.toString())
} else {
console.log(data);
}
})
getData
function so that it returns a promise. We can create a promise with new Promise(callback)
, where callback
is a function with two arguments: resolve
and reject
. We will call resolve
if we successfully obtain the data. If something goes wrong, we will call reject
..then
method on it to specify what should happen once resolve
or reject
is called.function getData(options) {
return new Promise(function(resolve, reject) { //create a new promise
$.get("process.php", options, function(response) {
resolve(JSON.parse(response)); //in case everything goes as planned
}, function() {
reject(new Error("AJAX request failed!")); //in case something goes wrong
});
});
}
// usage
getData({name: "John"}).then(function(data) {
console.log(data)
}, function(err) {
console.log("Error! " + err);
});
readFile("fileName")
.then(function(text) {
return tokenize(text);
})
.then(function(tokens) {
return parse(tokens);
})
.then(function(parseTree) {
return optimize(parseTree);
})
.then(function(optimizedTree) {
return evaluate(optimizedTree);
})
.then(function(output) {
console.log(output);
});