异步编程
异步背景
基于回调的异步编程
有一些异步行为的例子,例如加载脚本和模块:
index.js
function loadScript(src) {
const script = document.createElement('script');
script.src = src;
document.head.append(script);
}
loadScript('./foo.js');
console.log(1);
foo.js
console.log(2);
function foo() {
console.log('foo');
}
打印顺序是 1、2。这说明脚本 foo.js 会在 loadScript 函数执行完成后才运行。如果 loadScript 函数后面有其他代码,它们不会等到脚本加载完成后再执行。
如果我想在脚本加载后立即使用脚本里的 foo
函数,直接调用会报错:
loadScript('./foo.js');
foo();
接下来,添加一个 callback 函数作为 loadScript 的第二个参数,该函数应在脚本加载完成时执行。
function loadScript(src, callback) {
const script = document.createElement('script');
script.src = src;
script.onload = () => callback(script);
document.head.append(script);
}
loadScript('./foo.js', script => {
foo();
});
将 foo 函数放在回调函数中就能正常工作了。
这就是基于回调的异步编程。异步执行某项功能的函数应该提供一个 callback 参数,并在相应事件完成时调用。
如果需要多个异步操作,可以嵌套回调函数:
loadScript('1.js', function (script) {
loadScript('2.js', function (script) {
loadScript('3.js', function (script) {
// ...加载完所有脚本后继续
});
});
});