【Javascript】Js同步异步以及回调函数

一、前言

今天查看了requireJs方面的知识,看着看着就看到了JS中同步与异步操作的知识点,经过查阅了很多的资料,基本了解了JS的同步与异步的操作,其中涉及到的知识点如下:

  • 什么时同步和异步?
  • JS的是基于事件驱动的单线程语言,为啥会有异步操作这种多线程的操作???
  • 浏览器线程,浏览器内核线程间的合作?
  • JS的异步操作都有哪些?它是如何工作的?

二、js单线程

  • JS的单线程

单线程的含义是js只能在一个线程上运行,也就是说,同一时间只能做一件事情,其他的任务则会放在任务队列里面排队等等js线程处理。

但是值得注意的是,虽然js是单线程语言,但是并不代表浏览器内核中的js引擎线程只有一个。js引擎有多个线程,一个主线程,其他的线程配合主线程工作

三、为什么js选择单线程

与它的用途有关。作为浏览器脚本语言,Javascript主要用途是与用户互动,以及操作dom。这决定了它只能是单线程,否则会带来复杂的同步问题。比如,假设javascript同事有两个进程,一个线程在某个DOM阶段添加内容,另一个线程删除了这个节点,这是浏览器应该以哪一个线程为准?想要实现这个问题,肯定要加入线程锁这个概念,那就复杂多了。

单线程与异步确实不能同时成为一个语言的特性,JS选择成为单线程语言,所以它本身是不可能异步的,但是js的宿主环境(比如浏览器,Node)是多线程的,宿主通过某种方式,使得js具备异步的属性,如果你理解了,你会发现js的机制是多么的简单高效!

四、同步和异步

  • 同步:一次只能完成一件任务,如果有多个任务,必须排队
  • 异步:每一个任务有一个或者多个回调函数(callback),前一个任务执行后,把里面回调函数抛出来,给浏览器的另外一个线程处理。而后一个任务是不等待前一个任务结束就执行。
  • 一个例子来说明异步和同步:
<html>
<head>
    <title>异步与同步</title>
</head>
<body>
<script>
     setTimeout(function () {
          console.log("异步任务")
     })
     console.log("同步任务")
</script>
</body>
</html>

//输出:
//同步任务
//异步任务

//执行顺序:
//首先执行setTimeout,发现是个异步操作,就把这个异步操作丢给浏览器内核中的
//计时器线程,然后js主线程继续执行console.log("同步任务"),之后js主线程空闲,
//从任务队列里面获取异步操作任务,放到js主线程栈中执行,输出“异步任务”

      

五、异步的好处

  1.异步的好处

用一个同步与一个异步图进行说明,假设有四个任务(1、2、3、4),它们各自的执行时间都是10ms,其中,任务2是任务3的前置任务,任务2需要20ms的响应时间。

  2.适合的场景

可以看出,当我们的程序需要大量I/O操作和用户请求时,js这个具备单线程,异步,事件驱动多种气质的语言是多么应景!相比于多线程语言,它不必耗费过多的系统开销,同时也不必把精力用于处理多线程管理,相比于同步执行的语言,宿主环境的异步和事件驱动机制又让它实现了非阻塞I/O,所以你应该知道它适合什么样的场景了吧!

五、JS的异步操作有哪些

  • 定时器函数setTimeout(交给定时器线程处理)
  • 事件绑定(onclick、onkeydown....,交给事件触发线程处理)
  • AJAX(交给HTTP线程处理)
  • 回调函数

我们已经知道,js一直是单线程执行的,浏览器为了几个明显的耗时任务(上面四点),单独开辟线程解决耗时问题。但是JS除了这几个明显耗时问题外,可能我们自己写的程序里面也会有耗时函数,怎么解决?我们肯定不能直接开辟单独的线程,但是我们可以利用浏览器给我们开发的窗口(定时器线程事件触发线程

六、任务队列

因为Javascript被设计为单线程,意味着一次只能执行一个任务,所有任务都需要排队

原文地址:https://www.cnblogs.com/pengshengguang/p/8734769.html

时间: 2024-10-11 06:36:53

【Javascript】Js同步异步以及回调函数的相关文章

同步异步与回调函数

同步异步 1,同步 同步是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那个这个进程会一直等待下去,直到收到返回信息,才继续执行下去 from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor import os, random def task(i): print(f'{os.getpid()}开始了任务') time.sleep(random.randint(1,3)) print(f'{o

python_高级进阶(4)同步_异步_回调函数_阻塞

阻塞 阻塞: 程序运行时,遇到了IO,程序挂起,cpu被切走. 非阻塞 非阻塞: 程序没有遇到IO,程序遇到IO但是我通过某种手段,让cpu强行运行我的程序. ? #同步: 提交一个任务,自任务开始运行直到此任务结束(可能有IO),返回一个返回值之后,我在提交下一个#? #异步: 一次提交多个任务,然后我就直接执行下一行代码. 收取结果 : 1将所有的任务的结果统一回收. 2. 完成一个任务,返回一个结果. 给三个人发布任务: 同步: 先告知第一个人完成写书的任务,我从原地等待,等他两天之后完成

js表单提交回调函数

在研究表单的时候发现一个有意思的东西——在表单提交的时候如何保证数据全部提交完毕才会清空? 我们常用的<input type="reset" value="重置" />,或者jquery的$('input[name=xxx]')val(''),直接清空input的value值,都是单纯的直接清空,不会等待数据提交完毕后在清空,所以会有数据传输没完成就清空的情况,怎么解决? 搜索的时候发现一个答案——写一个回调函数,感觉不严谨.先记录下来,以后慢慢研究.

javaScript中的同步,异步与回调函数

for (var i = 0; i < 5; i++) { setTimeout(function() { console.log('i: ',i); }, 1000); } console.log(i); 输出结果: //输出 5 i: 5 i: 5 i: 5 i: 5 i: 5 记住我们的口诀,同步=>异步=>回调 1.for循环和循环体外部的console是同步的,所以先执行for循环,再执行外部的console.log.(同步优先) 2.for循环里面有一个setTimeout回

同步和异步以及回调函数

一.同步 <script type="text/javascript"> for(var i=0; i<100; i++){ //先执行循环* ,在输出222 console.log('*') } console.log(222); </script> 二.异步 <script type="text/javascript"> setInterval(function(){ //先输出111,再输出定时* console.lo

js同步-异步-回调

出处:https://blog.csdn.net/u010297791/article/details/71158212(1)上面主要讲了同步和回调执行顺序的问题,接着我就举一个包含同步.异步.回调的例子. let a = new Promise(//声明了一个Promise回调函数,能够使用then function(resolve, reject) { console.log(1) setTimeout(() => console.log(2), 0) console.log(3) cons

js同步异步执行顺序setTimeOut面试题分析

<script> for(var i=0;i<2;i++){ setTimeout(function(){ console.log(i); },0); } </script> // 结果:2,2 打印两个2而不是0,1,跟js执行顺序有关系. 所有的任务分为两种,一种是同步任务,一种是异步任务.同步任务是指在主线程上排队的任务.异步任务是指不进入主线程.而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异

Node.js:创建应用+回调函数(阻塞/非阻塞)

一.创建应用 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi.从这个角度看,整个"接收 HTTP 请求并提供 Web 页面"的需求根本不需要 PHP 来处理. 不过对 Node.js 来说,概念完全不一样了.使用 Node.js 时,我们不仅仅在实现一个应用,同时还实现了整个 HTTP 服务器.事实上,我们的 Web 应用以及对应的 Web 服务器基本上是一样的. 在我们创建 Node.js

JS 定时器&amp;异步任务与函数节流

定时器 JavaScript 提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务. 1)setTimeout setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行.它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器. var timer = setTimeout(func|code, delay); //第一个参数可以是函数也可以是代码块,第二个是延迟的时间,单位是毫