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回调,他是垫底的存在,只能最后执行。(回调垫底)

那么,为什么我们最先输出的是5呢?

非常好理解,for循环先执行,但是不会给setTimeout传参(回调垫底),

等for循环执行完,就会给setTimeout传参,而外部的console打印出5是因为for循环执行完成了。

这里涉及到JavaScript执行栈和消息队列的概念,概念的详细解释可以看阮老师的 JavaScript 运行机制详解:再谈Event Loop – 阮一峰的网络日志,或者看 并发模型与Event Loop。

javaScript单线程如何处理回调呢?

javaScript同步的代码是在堆栈中顺序执行的。而setTimeout回调会先放到消息队列,for循环每执行一次,就会

放一个setTimeout到消息队列中,排队等候,当同步代码执行完了,再去调用消息队列中的回调方法。

在这个经典例子中,也就是说,先执行for循环,按顺序放了5个setTimeout回调到消息队列,然后for循环结束,下面还有一个同步的console,执行完console之后,堆栈中已经没有同步的代码了,就去消息队列找,发现找到了5个setTimeout,注意setTimeout是有顺序的。

那么,setTimeout既然在最后才执行,那么他输出的i又是什么呢?答案就是5。。有人说不是废话吗?

现在告诉大家为什么setTimeout全都是5,JavaScript在把setTimeout放到消息队列的过程中,循环的i是不会及时保存进去的,相当于你写了一个异步的方法,但是ajax的结果还没返回,只能等到返回之后才能传参到异步函数中。

在这里也是一样,for循环结束之后,因为i是用var定义的,所以var是全局变量(这里没有函数,如果有就是函数内部的变量),这个时候的i是5,从外部的console输出结果就可以知道。那么当执行setTimeout的时候,由于全局变量的i已经是5了,所以传入setTimeout中的每个参数都是5。

时间: 2024-09-29 10:57:28

javaScript中的同步,异步与回调函数的相关文章

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

一.前言 今天查看了requireJs方面的知识,看着看着就看到了JS中同步与异步操作的知识点,经过查阅了很多的资料,基本了解了JS的同步与异步的操作,其中涉及到的知识点如下: 什么时同步和异步? JS的是基于事件驱动的单线程语言,为啥会有异步操作这种多线程的操作??? 浏览器线程,浏览器内核线程间的合作? JS的异步操作都有哪些?它是如何工作的? 二.js单线程 JS的单线程 单线程的含义是js只能在一个线程上运行,也就是说,同一时间只能做一件事情,其他的任务则会放在任务队列里面排队等等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. 完成一个任务,返回一个结果. 给三个人发布任务: 同步: 先告知第一个人完成写书的任务,我从原地等待,等他两天之后完成

android中出现的多处回调函数

回调函数的概念 android中出现的多处回调函数,比如去override 一些函数 OnCreate等等 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html android中出现的多处回调函数,布布扣,bubuko.com

JavaScript ES7 中使用 async/await 解决回调函数嵌套问题

原文链接:http://aisk.me/using-async-await-to-avoid-callback-hell/ JavaScript 中最蛋疼的事情莫过于回调函数嵌套问题.以往在浏览器中,因为与服务器通讯是一种比较昂贵的操作,因此比较复杂的业务逻辑往往都放在服务器端,前端 JavaScript 只需要少数几次 AJAX 请求就可拿到全部数据. 但是到了 webapp 风行的时代,前端业务逻辑越来越复杂,往往几个 AJAX 请求之间互有依赖,有些请求依赖前面请求的数据,有些请求需要并行

同步和异步以及回调函数

一.同步 <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

javascript与jQuery的each,map回调函数参数顺序问题

<script> var arr = [2,3,6,7,9]; //javascript中的forEach 和 map方法 arr.forEach(function(value,index){//(值,索引) console.log(value); }); arr.map(function(value,index){//(值,索引) console.log(value); }); //jQuery的 each map方法 $(arr).each(function(index,value){//

extjs中组件监听器里面的回调函数说明

近期在看项目源代码的时候发现了例如以下代码,当中_searchSupplierStore是JsonStore对象 _searchSupplierStore.on('beforeload',function(thiz,options){ thiz.baseParams["cusCode"]="%"+Ext.getCmp('id_cusCodetext').getValue()+"%"; thiz.baseParams["cusType&q

JavaScript中以构造函数的方式调用函数

转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明.函数表达式或者函数构造器(见以前的随笔)等方式来构造函数对象.函数构造器和其它函数的区别在与它们的调用方式不同. 要以构造函数的方式调用函数,只需要在调用时在函数名称前加new 关键字,比如:function whatsMyContext(){ return this; }; 调用:new what