JavaScript异步编程

声明

该文部分代码和内容节选自菜鸟教程,仅用作个人学习,特此声明

链接https://www.runoob.com/

JavaScript 异步编程

1、异步的概念

异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。

在我们学习的传统单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系。

简单来理解就是:同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高

以上是关于异步的概念的解释,接下来我们通俗地解释一下异步:异步就是从主线程发射一个子线程来完成任务。

img

2、什么时候用异步编程

在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。

现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。

为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞也不会影响主线程的运行。但是子线程有一个局限:一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将它合并到主线程中去的。

为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。

3、回调函数

回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。

回调函数练习

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>回调函数练习</title>
</head>
<body>

<p id="demo"></p>
<script>
    function print(){
        document.getElementById("demo").innerHTML = "这行文字会在函数print执行三秒后出现";
    }
    setTimeout(print,3000);
</script>

</body>
</html>

这段程序中的 setTimeout 就是一个3s的过程,它的第一个参数是个回调函数,第二个参数是毫秒,这个函数执行之后会产生一个子线程,子线程会等待 3 秒,然后执行回调函数 "print",在命令行输出 "这行文字会在函数print执行三秒后出现"。

其实,JavaScript语法是十分人性化的,我们不需要特意去单独定义一个函数,直接采用以下方式就好

setTimeout(function () {
    document.getElementById("demo").innerHTML="这行文字会在函数print执行三秒后出现";
}, 3000);

需要注意的是:setTime会在子线程中等待3s,但setTime函数执行之后主线程是没有停止的

主线程的任务会先一步执行,如下实例

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>主线程和子线程</title> 
</head>
<body>

<p>回调函数等待 3 秒后执行。</p>
<p id="demo1"></p>
<p id="demo2"></p>
<script>
setTimeout(function () {
    document.getElementById("demo1").innerHTML="RUNOOB-1!";
}, 3000);
document.getElementById("demo2").innerHTML="RUNOOB-2!";
</script>

</body>
</html>

主线程写入的"RUNOOB-2"会直接显示,子线程写入的"RUNOOB-1"会在程序执行3s后显示

posted @ 2022-05-03 21:40  无关风月7707  阅读(23)  评论(0编辑  收藏  举报