什么是 JavaScript 里的异步操作和回调函数

举报
汪子熙 发表于 2022/12/28 19:57:48 2022/12/28
【摘要】 JavaScript 宿主环境提供了许多功能,允许开发人员安排异步操作。 换句话说,我们可以立即触发一个动作,但这些动作需要耗费一定的时间才能完成执行。 setTimeout 函数就是一个典型的例子。

JavaScript 宿主环境提供了许多功能,允许开发人员安排异步操作。 换句话说,我们可以立即触发一个动作,但这些动作需要耗费一定的时间才能完成执行。

setTimeout 函数就是一个典型的例子。

看看函数 loadScript(src),它使用给定的 src 加载脚本:

function loadScript(src) {
  // creates a <script> tag and append it to the page
  // this causes the script with given src to start loading and run when complete
  let script = document.createElement('script');
  script.src = src;
  document.head.append(script);
}

上述代码创建一个 <script> 标记并将其附加到页面。 这会导致具有给定 src 的脚本开始加载并在完成时运行。

消费方式也很简单:

// load and execute the script at the given path
loadScript('/my/script.js');

该脚本是 异步执行的,因为它现在开始加载,但实际脚本的运行逻辑,绝大多数时候发生在函数 loadScript 已经完成时。

如果 loadScript(…) 下面有任何代码,这些代码会立即执行,而不会等待脚本加载完成再执行。

假设我们需要在新脚本加载后立即使用它。 它声明了新函数 newFunction,我们想要运行这个函数。

但是如果我们在 loadScript(…) 调用之后立即调用 newFunction,那就行不通了:

loadScript('/my/script.js'); // the script has "function newFunction() {…}"

newFunction(); // no such function!

上面的代码根本不能正常工作。

自然,浏览器可能没有时间加载脚本。 到目前为止, loadScript 函数还没有提供跟踪加载完成的方法。 脚本加载并最终运行,仅此而已。 但我们想知道它何时发生,使用该脚本中的新函数和变量。

让我们添加一个回调函数作为 loadScript 的第二个参数,它应该在脚本加载时执行:

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;

  script.onload = () => callback(script);

  document.head.append(script);
}

onload 事件用于在脚本加载执行后执行一个函数。

现在,如果我们想从脚本中调用新函数,我们应该在回调中写下:

loadScript('/my/script.js', function() {
  // the callback runs after the script is loaded
  newFunction(); // so now it works
  ...
});

一个实际消费 loadScript 的例子:

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;
  script.onload = () => callback(script);
  document.head.append(script);
}

loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
  alert(`Cool, the script ${script.src} is loaded`);
  alert( _ ); // _ is a function declared in the loaded script
});
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。