开心档之JavaScript 异步编程

2023-09-21 23:19:36

JavaScript 异步编程
 

目录

JavaScript 异步编程

异步的概念

什么时候用异步编程

回调函数

实例

实例

实例

异步 AJAX

实例

实例


 

 

异步的概念

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

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

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

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

 

什么时候用异步编程

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

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

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

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

回调函数

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

实例

function print() {
    document.getElementById("demo").innerHTML="RUNOOB!";
}
setTimeout(print, 3000);

 

这段程序中的 setTimeout 就是一个消耗时间较长(3 秒)的过程,它的第一个参数是个回调函数,第二个参数是毫秒数,这个函数执行之后会产生一个子线程,子线程会等待 3 秒,然后执行回调函数 "print",在命令行输出 "RUNOOB!"。

当然,JavaScript 语法十分友好,我们不必单独定义一个函数 print ,我们常常将上面的程序写成:

实例

setTimeout(function () {
    document.getElementById("demo").innerHTML="RUNOOB!";
}, 3000);

 

**注意:**既然 setTimeout 会在子线程中等待 3 秒,在 setTimeout 函数执行之后主线程并没有停止,所以:

实例

setTimeout(function () {
    document.getElementById("demo1").innerHTML="RUNOOB-1!";
}, 3000);
document.getElementById("demo2").innerHTML="RUNOOB-2!";
console.log("2");

 

这段程序的执行结果是:


RUNOOB-1!
RUNOOB-2!

异步 AJAX

除了 setTimeout 函数以外,异步回调广泛应用于 AJAX 编程。有关于 AJAX 详细请参见:https://www.kxdang.com/topic//ajax/ajax-tutorial.html

XMLHttpRequest 常常用于请求来自远程服务器上的 XML 或 JSON 数据。一个标准的 XMLHttpRequest 对象往往包含多个回调:

实例

var xhr = new XMLHttpRequest();
 
xhr.onload = function () {
    // 输出接收到的文字数据
    document.getElementById("demo").innerHTML=xhr.responseText;
}
 
xhr.onerror = function () {
    document.getElementById("demo").innerHTML="请求出错";
}
 
// 发送异步 GET 请求
xhr.open("GET", "https://www.kxdang.com/topic//try/ajax/ajax_info.txt", true);
xhr.send();

 

XMLHttpRequest 的 onload 和 onerror 属性都是函数,分别在它请求成功和请求失败时被调用。如果你使用完整的 jQuery 库,也可以更加优雅的使用异步 AJAX:

实例

$.get("https://www.kxdang.com/topic//try/ajax/demo_test.php",function(data,status){
    alert("数据: " + data + "\n状态: " + status);
});

 

更多推荐

驱动开发---基于gpio子系统编写LED灯的驱动

一、GPIO子系统相关API1.解析GPIO相关的设备树节点structdevice_node*of_find_node_by_path(constchar*path)功能:根据设备树节点路径解析设备树节点信息参数:path:设备树所在的节点路径/mynode@0X12345678返回值:成功返回目标节点首地址,失败返

第33节——useRef

一、概念useRef,他的作用是“勾住”某些组件挂载完成或重新渲染完成后才拥有的某些对象,并返回该对象的引用。该引用在组件整个生命周期中都固定不变,该引用并不会随着组件重新渲染而失效。返回一个可变的ref对象,该对象只有个current属性,初始值为传入的参数(initialValue)。返回的ref对象在组件的整个生

【ROS】机器人使用Nomachine进行远程控制

官网:NoMachine-FreeRemoteDesktopforEverybody支持的系统:WindowsMacLinux树莓派其他ARM板IOSAndroid由于网速问题,可以使用我下载好的:(8.8.1_1)链接:https://pan.baidu.com/s/16v6jn8a-dcVbIxGI3bI2QA提取

60+开源数据集资源大合集(医学图像、卫星图像、语义分割、自动驾驶、图像分类等)

1.医学图像疟疾细胞图像数据集下载链接:http://suo.nz/2VQTUt皮肤癌MNIST:HAM10000下载链接:http://suo.nz/33n6Xy该数据集收集了来自不同人群的皮肤镜图像,通过不同的方式获取和存储。最终数据集包含10015张皮肤镜图像,可用作学术机器学习目的的训练集。案例包括色素病变领域

记一次 Java Testcontainers CPU 100% 问题排查过程

以为代码进入了死循环,结果并没有!文章目录背景与问题排查过程代码路经确认内存分析咨询okio社区等等,好像并没有死循环能否从内存快照发现其他问题?背景与问题本问题来源于ShardingSphereissue:Integrationtestsoccasionallystuckinwaitingforcontainerre

C++之template可变模板参数应用总结(二百二十八)

简介:CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注:Android系统攻城狮1.前言本篇目的:C++之

步步为营,如何将GOlang引用库的安全漏洞修干净

文章目录引场景构建第一步、直接引用的第三方库升级修复策略1.确认是否为直接引用的第三方库2.找到需要升级的版本是否为release版本第二步、间接引用的第三方库升级修复策略那么问题来了,我们这么间接引用库的对应的直接引用库是哪个呢?(一)没有release版本,但直接引用库有最新的代码可升级(1)将最新代码下载到项目某

Redis 集合(Set)快速指南 | Navicat

Redis支持通过多种数据类型来存储项目集合。其中,包括列表、集合和哈希。上周的博文介绍了列表(List)数据类型并重点介绍了一些用于管理列表(List)的主要命令。在今天的文章中,我们将转向关注集合(Set)数据类型。在Redis中,集合(Set)与列表(List)相似,但是,集合(Set)中的元素是无序的,并且每个

skywalking入门

参考:https://www.jianshu.com/p/ffa7ddcda4ab参考:https://developer.aliyun.com/article/1201085skywalking(APM)调用链路分析以及应用监控分析工具Skywalking主要由三大部分组成:agent、collector、webap

行为型模式-策略模式和责任链模式对比

一、区别:目的和问题解决方式:策略模式的主要目的是将一组算法或行为封装成独立的策略对象,并使客户端能够在运行时选择其中一个策略来执行。这种模式通常用于实现相同操作的不同算法或策略之间的切换和替换。责任链模式的主要目的是将请求的发送者和接收者解耦,允许多个对象依次处理请求,直到其中一个对象能够处理请求为止。责任链模式通常

opencv dnn模块 示例(16) 目标检测 object_detection 之 yolov4

博客【opencvdnn模块示例(3)目标检测object_detection(2)YOLOobjectdetection】测试了yolov3及之前系列的模型,有在博客【opencvdnn模块示例(15)opencv4.2版本dnn支持cuda加速(vs2015异常解决)】说明了如何使用dnn模块进行cuda加速推理。

热文推荐