精华内容
下载资源
问答
  • 同步和异步区别是什么? 场景题:12345以什么顺序打印出来?定时器的应用 知识点: 单线程和异步 应用场景 Callback hell(回调地狱) 和 Promise(解决回调地狱的问题) 单线程和异步: JS是单线程语言,只能同时...

    同步和异步的区别是什么?

    场景题:12345以什么顺序打印出来?定时器的应用
    在这里插入图片描述
    知识点:

    1. 单线程和异步
    2. 应用场景
    3. Callback hell(回调地狱) 和 Promise(解决回调地狱的问题)

    单线程和异步:

    1. JS是单线程语言,只能同时做一件事儿 (例子:做一个ajax请求去加载资源,或者说弄一个定时器,先等待1秒钟后干嘛,如果按照单线程这个只能同时做一件事儿,那么它在这个事情中,它就卡住了,卡住的话鼠标点不了,js不执行。这就是同时做一件事,这就是js单线程的本质。)
    2. 浏览器和node.js已支持JS启动进程,如Web Worker
    3. Js和DOM渲染共用同一个线程,因为JS可修改DOM结构
    一、	遇到等待(网络请求,定时任务)不能卡住
    二、	需要异步(解决单线程等待的问题)
    三、	异步基于callback函数形式来调用的
    

    在这里插入图片描述

    异步 核心代码演示:

    //异步 (callback 回调)
    console.log(100)
    setTimeout(() => {
        console.log(200)
    },1000)
    console.log(300)
    

    效果:
    在这里插入图片描述
    什么叫异步呢?就是说

    先打印100,遇到setTimeOut就先记下,1秒钟后再执行,先不管它,到时候执行再说,程序会立马向下执行,立马等于300,打印了300之后,整个的程序执行完成,然后发现异步任务中还有一个任务,就是一个函数

    () => {
    console.log(200)
    },1000)
    

    一秒钟之后执行,那一秒钟之后就执行刚才说的打印这个200,所以说异步是通过callback的形式去调用的。callback就是回调,就是说回调函数,这个就是回调函数

    () => {
    console.log(200)
    },1000)
    

    也就是说,每个异步都需要加个回调函数,回调函数的意思就是说:我们先去执行同步任务(不是异步的任务),执行完之后,到一个时间,比如上面是触发时间1秒,我们再去执行回调函数,这就是异步。

    异步的特点是:它不会阻塞后面代码的执行

    同步 核心代码演示:

    //同步
    console.log(100)
    alert(200)
    console.log(300)
    

    效果:
    在这里插入图片描述
    点击OK后
    在这里插入图片描述
    同步:在alert(200)的时候,它就卡住了,也就是像我们刚才描述的那样,如果是同步的话,它会在运行的过程中卡住,后面的程序不会执行,浏览器也不会渲染,然后js代码也不会执行,这就是同步。

    异步和同步总结:

    1. 基于JS是单线程语言
    2. 异步不会阻塞代码执行
    3. 同步会阻塞代码执行
    展开全文
  • js同步和异步区别 单线程是什么 我们常说“JavaScript是单线程的”。所谓单线程,就是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个,一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务...

    js同步和异步的区别

    单线程是什么

    我们常说“JavaScript是单线程的”。所谓单线程,就是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个,一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。如果一个任务耗时过长,那么后面的任务就必须一直等待下去,会拖延整个程序。我们不妨叫它主线程。

    但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等。这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分。不妨叫它们工作线程。

    同步和异步

    "同步模式"就是后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。

    如在函数A返回的时候,调用者就能够得到预期结果(即拿到了预期的返回值或者看到了预期的效果),那么这个函数就是同步的。

    "异步模式"则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

    如在函数A返回的时候,调用者还不能够得到预期结果,而是需要在将来通过一定的手段得到,那么这个函数就是异步的。

    其实同步和异步,无论如何,做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。

    下面以AJAX请求为例,来看一下同步和异步的区别:

    • 异步AJAX

    • 主线程:“你好,AJAX线程。请你帮我发个HTTP请求吧,我把请求地址和参数都给你了。”

    • AJAX线程:“好的,主线程。我马上去发,但可能要花点儿时间呢,你可以先去忙别的。”

    • 主线程:“谢谢,你拿到响应后告诉我一声啊。”

    • (接着,主线程做其他事情去了。一顿饭的时间后,它收到了响应到达的通知。)

    • 同步AJAX

    • 主线程:“你好,AJAX线程。请你帮我发个HTTP请求吧,我把请求地址和参数都给你了。”

    • AJAX线程:“…”

    • 很久以后…

    • AJAX线程:“主线程,不好意思,我在工作的时候不能说话。你的请求已经发完了,拿到响应数据了,给你。”

    正是由于JavaScript是单线程的,而异步容易实现非阻塞,所以在JavaScript中对于耗时的操作或者时间不确定的操作,使用异步就成了必然的选择。

    再举一个例子:
    在这里插入图片描述
    输出顺序是:
    在这里插入图片描述

    可见,尽管我们设置了setTimeout(function,time)中的等待时间为0,结果其中的function还是后执行。

    尽管setTimeout的time延迟时间为0,其中的function也会被放入一个队列中,等待下一个机会执行,当前的代码(指不需要加入队列中的程序)必须在该队列的程序完成之前完成,因此结果可能不与预期结果相同。

    异步过程的构成要素

    从上文可以看出,异步函数实际上很快就调用完成了。但是后面还有工作线程执行异步任务、通知主线程、主线程调用回调函数等很多步骤。我们把整个过程叫做异步过程。异步函数的调用在整个异步过程中,只是一小部分。

    总结一下,一个异步过程通常是这样的:

    主线程发起一个异步请求,相应的工作线程接收请求并告知主线程已收到(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)。

    异步函数通常具有以下的形式:

    img

    它可以叫做异步过程的发起函数,或者叫做异步任务注册函数。args是这个函数需要的参数。callbackFn也是这个函数的参数,但是它比较特殊所以单独列出来。所以,从主线程的角度看,一个异步过程包括下面两个要素:发起函数(或叫注册函数)A和回调函数callbackFn。它们都是在主线程上调用的,其中注册函数用来发起异步过程,回调函数用来处理结果。

    举个栗子

    img

    其中的setTimeout就是异步过程的发起函数,fn是回调函数。

    注意:前面说的形式A(args…, callbackFn)只是一种抽象的表示,并不代表回调函数一定要作为发起函数的参数,例如:

    img

    发起函数和回调函数就是分离的。

    消息队列和事件循环

    上文讲到,异步过程中,工作线程在异步操作完成后需要通知主线程。这个通知机制是利用消息队列和事件循环实现的。

    用一句话概括:工作线程将消息放到消息队列,主线程通过事件循环过程去取消息。

    • 消息队列:消息队列是一个先进先出的队列,它里面存放着各种消息。
    • 事件循环:事件循环是指主线程重复从消息队列中取消息、执行的过程。

    实际上,主线程只会做一件事情,就是从消息队列里面取消息、执行消息,再取消息、再执行。当消息队列为空时,就会等待直到消息队列变成非空。而且主线程只有在将当前的消息执行完成后,才会去取下一个消息。这种机制就叫做事件循环机制,取一个消息并执行的过程叫做一次循环。

    事件循环用代码表示大概是这样的:

    img

    那么,消息队列中放的消息具体是什么东西?消息的具体结构当然跟具体的实现有关,但是为了简单起见,我们可以认为:消息就是注册异步任务时添加的回调函数。

    再次以异步AJAX为例,假设存在如下的代码:

    img

    主线程在发起AJAX请求后,会继续执行其他代码。AJAX线程负责请求segmentfault.com,拿到响应后,它会把响应封装成一个JavaScript对象,然后构造一条消息:

    img

    其中的callbackFn就是前面代码中得到成功响应时的回调函数。

    主线程在执行完当前循环中的所有代码后,就会到消息队列取出这条消息(也就是message函数),并执行它。到此为止,就完成了工作线程对主线程的通知,回调函数也就得到了执行。如果一开始主线程就没有提供回调函数,AJAX线程在收到HTTP响应后,也就没必要通知主线程,从而也没必要往消息队列放消息。

    用图表示这个过程就是:

    img

    从上文中我们也可以得到这样一个明显的结论,就是:异步过程的回调函数,一定不在当前这一轮事件循环中执行。

    异步与事件

    上文中说的“事件循环”,为什么里面有个事件呢?那是因为:消息队列中的每条消息实际上都对应着一个事件。

    上文中一直没有提到一类很重要的异步过程:DOM事件。举例来说:

    img

    从事件的角度来看,上述代码表示:在按钮上添加了一个鼠标单击事件的事件监听器;当用户点击按钮时,鼠标单击事件触发,事件监听器函数被调用。

    从异步过程的角度看,addEventListener函数就是异步过程的发起函数,事件监听器函数就是异步过程的回调函数。事件触发时,表示异步任务完成,会将事件监听器函数封装成一条消息放到消息队列中,等待主线程执行。

    事件的概念实际上并不是必须的,事件机制实际上就是异步过程的通知机制。我觉得它的存在是为了编程接口对开发者更友好。

    另一方面,所有的异步过程也都可以用事件来描述。例如:setTimeout可以看成对应一个时间到了!的事件。前文的setTimeout(fn, 1000);可以看成:

    img

    生产者与消费者

    从生产者与消费者的角度看,异步过程是这样的:工作线程是生产者,主线程是消费者(只有一个消费者)。工作线程执行异步任务,执行完成后把对应的回调函数封装成一条消息放到消息队列中;主线程不断地从消息队列中取消息并执行,当消息队列空时主线程阻塞,直到消息队列再次非空。

    总结

    最后再用一个生活中的例子总结一下同步和异步:在公路上,汽车一辆接一辆,有条不紊的运行。这时,有一辆车坏掉了。假如它停在原地进行修理,那么后面的车就会被堵住没法行驶,交通就乱套了。幸好旁边有应急车道,可以把故障车辆推到应急车道修理,而正常的车流不会受到任何影响。等车修好了,再从应急车道回到正常车道即可。唯一的影响就是,应急车道用多了,原来的车辆之间的顺序会有点乱。

    这就是同步和异步的区别。同步可以保证顺序一致,但是容易导致阻塞;异步可以解决阻塞问题,但是会改变顺序性。改变顺序性其实也没有什么大不了的,只不过让程序变得稍微难理解了一些 😃

    应急车道回到正常车道即可。唯一的影响就是,应急车道用多了,原来的车辆之间的顺序会有点乱。

    这就是同步和异步的区别。同步可以保证顺序一致,但是容易导致阻塞;异步可以解决阻塞问题,但是会改变顺序性。

    展开全文
  • js异步和同步区别

    2020-07-09 13:35:57
    单线程和异步: dom渲染中js必须停止,js进行过程中dom渲染必须停止 单线程是异步出现的一个背景 二.异步和同步: 异步的例子,在定时器1s内,会输出300 而在同步中,200的警示框必须点击确定后才能输出300 ...

    js异步和同步的区别

    一.单线程和异步:
    在这里插入图片描述
    dom渲染中js必须停止,js进行过程中dom渲染必须停止
    在这里插入图片描述

    单线程是异步出现的一个背景

    二.异步和同步:
    在这里插入图片描述
    异步的例子,在定时器1s内,会输出300
    而在同步中,200的警示框必须点击确定后才能输出300
    在这里插入图片描述

    展开全文
  • 关于labwindows-cvi学习,参考例程编程学习,关于异步定时器和同步定时器区别,关于异步定时器和同步定时器区别
  • 大纲1. Javascript的单线程2. Javascript中的异步原理2.1. 两组概念2.2. Javascript中的异步3. 事件任务队列3.1. EventLoop的解释4.... 定时器区别最近心血来潮,准备整理一下Javascript中有关异步编程方面的...
         

    最近心血来潮,准备整理一下Javascript中有关异步编程方面的东西,写几篇文章。当然同时也是为了沉淀一下自己所学。

    暂时将这个专题命名为Javascript异步编程专题吧,目前包含以下几篇文章,


    本篇文章是本专题的第一篇文章。

    正文开始。

    Javascript这门语言出身“低贱”,但是随着近年来社区的活跃,反而给人以耀眼的活跃。同时带来的也是各种各样的对这门原先被当作玩具语言的解析。本篇文章将会带了Javascript中关于异步编程以及其周边内容的介绍。

    Javascript的单线程

    Javascript是单线程的。javascript的程序员一定要时刻谨记这句话。

    可以说单线程是Javascript语言最本质的特性之一。言外之意,Javascript引擎在运行js代码的时候,同一个时间只能执行单个任务。

    这是为何呢?

    其实这跟Javascript的历史有关系。Javascript最初被设计成一种浏览器脚本语言,决策者们仅仅是需要一门轻量的浏览器脚本语言来做一些简单的用户交互及DOM操作。在这样一个背景下,据说Javascript的设计者仅仅花了10天就完成了这门语言的设计。

    相比多线程,单线程不需要考虑创建线程、销毁线程、线程间通信等等诸如此类的复杂问题。所以,为了避免复杂性,Javascript从诞生伊始就是单线程,而且日后也应该不会改变这一特性。

    Javascript中的异步原理

    在C#、Java等语言中,异步操作往往是创建一个线程来执行异步任务,异步任务执行完毕之后再将执行结果通知给主线程。这其中往往会伴随着,多线程、线程池、并发等相关术语。但是在Javascript中不存在这些。

    如前文所述,Javascript是单线程的,那么Javascript的异步是怎么回事呢?Javascript又是如何在单线程上给出所谓的异步编程呢?

    两组概念

    在解释这个问题之前,我们应该首先明确两组概念。就是同步异步以及阻塞非阻塞这两组概念。

    首先这是两组不同的概念。同步、异步一般指的是消息的通信机制;而阻塞、非阻塞一般强调的是程序在等待(消息)时的状态。

    他们的概念如下,

    名称解释备注
    同步发出一个功能调用(执行函数)时,在没有得到调用结果之前,该调用就不会返回-
    异步发出一个调用后,不关心结果返回,而是立即返回。结果出来后,将会通过一些额外手段通知调用者注1
    阻塞在调用结果返回之前,当前线程会被挂起等待。直到得到结果之后函数调用才会返回。-
    非阻塞在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。-

    注1:这里所说的额外手段,往往是指异步调用的一些具体实现方式,比如事件监听、轮询等等。

    可见,同步、异步和阻塞、非阻塞是两组概念,我们不应该混淆他们。同时,这两组概念其实是可以共存,可以混合搭配最多四种模式。

    后面我们会说到其实Javascript中的异步并非真正意思上的异步,它最多能做到非阻塞的地步。所以Node.js官网在介绍自己时仅仅是说“基于事件驱动”,“非阻塞IO模型”,并没有提到异步的字眼。

    好了,关于这两组概念虽然还有许多可以说的内容,不过这篇文章的重点并不是介绍这两组概念,有兴趣的可自行查阅相关资料。

    Javascript中的异步

    让我们言归正传。在Javascript中,什么样的调用可以算是异步调用呢?

    我个人认为,Javascript中异步的应用场景主要有两个,其一是基于浏览器的各种异步IO和事件监听其二是Javascript代码中的关于定时器(setTimeoutsetInterval)的应用。

    对于异步IO,比如ajax请求(当然,ajax分为同步ajax和异步ajax,这里我们仅用异步ajax来作示例)。当js代码发出一个ajax请求时,浏览器仍然会接着往下执行js代码。我们将处理ajax返回的逻辑绑定在ajax回调函数上,当ajax请求完毕成功返回时会触发回调函数,然后接着执行我们绑定的处理逻辑。如下图,

    这种场景下的异步其实涉及到了两个线程,一个是javascript线程,一个是浏览器为了发出ajax请求而开辟的线程(它属于浏览器进程的子线程)。

    对于定时器的异步场景,我们可以用一段示例代码来说明,


    function foo(callback) {
        console.log('foo start');
        setTimeout(function() {
            callback();
        }, 2000);
        console.log('foo end');
    }
    function foo2() {
        console.log('Hello!');
    }
    foo(foo2);

    这段代码的执行过程如下图,

    从图中我们可以看出执行foo(foo2)使用了50ms,其中在1010ms时开始执行setTimeout语句。由于我们使用setTimeout设置了一个延时,所以在执行foo(foo2)时并没有真正的执行foo2(),而是将其时机推迟了。直到3010ms左右时才去真正的执行foo2()的代码。

    ,为了方便叙述,上述时间都是假设的,不必纠结。下同。)


    从上图中可以看出,整个执行过程中只有一个javascript线程,异步调用的部分的代码,最终也是在javascript线程上执行的,只不过被延迟了。

    从上面的两个示例中,我们足以管中窥豹。笼统的说,单线程的Javascript中其实没办法实现真正意义上的异步,Javascript中所谓的异步可以理解成延迟执行

    事件和任务队列

    往往在Javascript运行环境中,除了Javascript线程之外,还有会有一个专门维护任务队列的线程。说到这里,有人会问,不是说好的Javascript是单线程吗?怎么这里会有两个线程?

    好问题!注意这里我并没有说Javascript语言,而是Javascript运行环境(Javascript Runtime)。常见的运行环境有各种浏览器(浏览器中的Javascript解释引擎),Nodejs环境等等。

    这里我们就以浏览器环境作为示例来进行相关说明。首先试想一下我们现在有这样的一个场景。我们在一段js代码中发出了一个ajax请求,同时给click和press注册了事件监听。那么当我们执行这段代码后,其效果图如下,

    因为Javascript是单线程的,就意味着Javascript同一时间只能处理一个任务。如果一旦任务产生的速度过快,那么后续的任务就得排队。每一个任务往往与一个事件相对应。

    如上图所示,当浏览器的用于ajax的线程得到ajax返回结果后会产生一个事件,将其放入任务队列。(其实这里还涉及到Ajax线程如何通知任务队列等等问题,这里我们就不讨论了)

    除此之外,可能用户还在页面进行了鼠标点击操作和按下键盘输入。这两个动作都将会产生一个事件,将产生的事件压入任务队列。

    EventLoop的解释

    上图中还有一个叫做Event Loop的东西,这个东西是什么东西呢?

    Event Loop是一个程序结构,用于等待和发送消息和事件。(a programming construct that waits for and dispatches events or messages in a program.)

    简单来说,EventLoop也是一个程序,它会不停的轮询任务队列中的事件。如果Javascript线程空了,则取出任务队列的第一个事件(这里是指主线程,如下图),然后找到此事件的处理函数并执行处理函数。当前一个事件执行完了(此时Javascript又会空下来),那么继续取出任务队列中的下一个事件。如此往复。

    回到我们上面的例子中,当从任务队伍队列中取出第一个事件时(Ajax返回事件),Javascript线程将会去执行函数foo1。其实从图中可以看出,先前绑定的三个回调函数最终都是在Javascript线程上执行的,只不过由于任务队列的存在,导致了他们的执行时机是不一样的。


    Javascript中的定时器

    Javascript中内置了两个方法,用于设置定时任务。分别是setTimeoutsetInterval。它们的具体用法我这里不展开说了。

    前文有提到过,在Javascript中常见的有两种异步场景,一种是异步IO,另一种就是定时任务。

    JQuery的作者John Resig有一篇文章,就是探讨Javascript中的定时器是如何工作的。我觉得大神文章中的示例对setTimeoutsetInterval的运行原理,以及它们在Javascript中是如何与异步任务协调工作的,说明的都非常好。我这里就直接拿过来用了。

    首先我们来看一张场景图,

    乍一看这张图一坨方块加一坨英文,看不出头绪。其实Javascript定时器的秘密就隐藏在其中,让我们一步一步来解析。

    图中深蓝色的方块可以理解成Javascript线程的执行过程,左侧是时序。右侧是对每一个Javascript代码发生了什么事作的说明。

    先看第一个Javascript代码块,它在整个时序中占用了不到20ms(大概18ms的样子),它依次发生哪些事情呢?

    • 初始化了一个10ms的setTimeout定时器
    • 鼠标被点击了一次
    • 初始化了一个10ms的setInterval定时器
    • 触发10ms的Timer定时器

    我们发现

    • 发生了一次鼠标点击,将产生一个鼠标click事件,此事件将会压入任务队列,等待执行。
    • Timer计时器的回调实际上会在第一个代码块执行完毕前被触发。但是这里注意的是,它不会立即执行(单线程上不能这样做,因为当前的Javascript线程还在处理第一个代码块呢)。实际上,触发的回调将被排成一个队列,等待下一个可执行时间。

    直到Javascript执行完第一块js代码,我们的任务队列中已经有两个待执行的任务了。如下,

    现在Javascript线程已经处于空闲状态了,此时任务队列已经有2个任务在等待执行了,按照入队顺序,我们先处理click事件。队列后面的任务继续排队等待。

    回到场景图中,我们现在开始处理click事件,即执行click事件绑定的回调函数。这其中触发了一次10ms的Interval定时器。但是此时Javascript线程上正在执行click事件的回调,所以即使Interval触发了,但是并不能执行。怎么办呢?只能对它说不好意思了,让它去排队吧。

    此时,任务队列的情况如下,

    可以看到,之前的click事件已经出队了,但是又新增了一个Interval定时器回调。

    随着时间的推移,在完成click事件任务完成之后,继续从任务队列中取出任务。从上图可知,下一个任务是Timer定时器的回调。

    我们在执行Timer定时器任务时,发现又有一个Interval定时器触发了。不过此时Javascript线程还在执行Timer定时器的任务呢,所以刚触发的Interval定时器任务只能去排队了。

    此时,任务队列如下,

    现在任务队列里面已经有两个一样的Interval定时器任务在等待执行了。


    :John Resig的原文中说,在Timer定时器执行期间触发的Interval定时器会被Dropped。起先我百思不得其解。按道理应该将其入队才对啊。后又仔细研读了原文,外加查阅了相关资料,终于知道是为何了。

    在John Resig的原文中,他给出的两个定时器的初始化如下,


    var id = setTimeout(fn, delay);
    var id = setInterval(fn, delay);

    关键的地方来了,这里setTimeoutsetInterval使用的回调函数都是同一个函数fn。在这种先提条件下,在前面的分析中,当Javascript正在执行Timer定时器的回调时,虽然又一次触发了Interval回调,但是由于两个定时器采用回调都是同一个函数。所以导致此时被触发的Interval定时器由于绑定的回调函数正在被执行,所以此次触发就被抛弃了


    让我们继续回到分析之中来。

    Timer定时器的回调执行完毕之后,我们与之前一样,从任务队列中取出下一个任务。这次是Interval定时器的回调。

    因为John Resig给的示例中,Interval定时器的回调执行将在10ms之内完成,所以按照上述的分析如此往复之后,最后将会出现Javascript线程空等的情况。

    在40-50ms这段时间之内,我们将积累的两个Interval定时器任务执行完毕了,发现任务队列中没有等待执行的任务了。那么接下来Javascript线程就会处于“空等”状态。

    在50ms的时候,有一个Interval定时器触发了。我们同样将其入队。不过由于之前任务队列本来就是空的,所以这个触发就立马执行了。

    定时器的时间精度问题

    根据前文所述,其实不管是setTimeout还是setInterval定时器,因为Javascript的单线程缘故,他们当在任务量较多的时候,都会涉及到一个排队等待执行的问题。所以定时器的对于时间间隔的把握其实不是那么精确的。

    就拿前文的例子来说,如果click事件的回调要消耗1000ms,那么后面的TimerInterval定时器的回调都得等着,直接click事件的回调执行完毕。所以真正等到定时器回调执行时,可能早就过了原先设定的10ms了。

    这点对于setInterval的影响更为严重。比如,


    setInterval(function(){
      console.log(2);
    },1000);
    (function (){
      sleeping(3000);
    })();

    上面的第一行语句要求每隔1000毫秒,就输出一个2。但是,第二行语句需要3000毫秒才能完成,请问会发生什么结果?

    结果就是等到第二行语句运行完成以后,立刻连续输出三个2,然后开始每隔1000毫秒,输出一个2。也就是说,setIntervel具有累积效应,如果某个操作特别耗时,超过了setInterval的时间间隔,排在后面的操作会被累积起来,然后在很短的时间内连续触发,这可能或造成性能问题(比如集中发出Ajax请求)。

    setTimeout(fn, 0)的理解

    记得以前有被人问过这句代码的含义????????????。

    按照常规理解,定时器的延时参数为0,表示是立即执行么?显然不是。

    不管如何,只要经过setTimeout操作,那么fn将会被放到任务队列中排队。我们说一旦进行了任务队列,何时能执行那就由不得你了。得看排在你前面的任务是不是耗时任务。

    所以这里延时参数的含义只有一个。那就是让fn早点去排队!如果任务队列中没有其他待执行任务,那么此时将会直接执行fn,其实这跟直接执行fn的区别不大。如果队列前面有待执行任务,那不好意思,你等着吧。

    定时器的区别

    其实setTimeoutsetInterval这两个定时器是有区别的。当然我想说的区别并不是指它们功能上的区别。

    Timer定时器在触发时,会将其回调任务压入任务队列进行排队。而Interval定时器在触发时,它不管当前Javascript线程的状态,它会无差别的往任务队列中压任务。如果某一个任务执行时占用了较多的Javascript线程时间,可能会导致Interval定时器连续压入多个回调。导致本来应该存在时间间隔的Interval定时器回调连续执行。

    此外,当Interval定时器回调正在被当前Javascript线程运行时,此次Interval定时器触发将会被抛弃。因为此次触发的Interval定时器回调不会被入队。《Javascript高级程序设计》一书中也提到了这一点,

    当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中。

    如果你对Interval定时器的时间间隔要求比较严格的话,可以尝试使用循环加setTimeout的方式来模拟setInterval的功能。


    展开全文
  • 定时器setTimeout()案例:五秒后自动关闭广告停止setTimeout()定时器setInterval()案例:倒计时停止setInterval()定时器案例:发送短信this指向4.JS执行机制JS单线程同步和异步5.location对象5.1 URL5.2 location...
  • 2、宏列队:用来保存待执行的宏任务(回调),比如:定时器回调/DOM事件回调/ajax回调 3、微列队:用来保存待执行的微任务(回调),比如:promise回调/MutationObserver回调 4、JS执行时会区别这两个队列 JS引擎...
  • ajax,每一个前端开发都用过,都知道它一般是异步的,也能同步使用。 聊天是需要长连接的,在一些场景下我们不想使用比较耗费资源的长连接,又想实现数据监听,这时候我们就会使用ajax的轮询 ajax轮询一般分为两种...
  • 什么是AJAX?...ajax技术可以实现整个页面无刷新同步和异步区别异步:同时执行,也叫并发执行。(统筹,定时器是异步执行的。生活中的同步是AJAX的异步顺序。)同步:顺序执行,(js中的代码执行过程就...
  • js宏任务微任务

    2021-02-12 22:02:30
    是什么 宏任务微任务是异步...宏任务微任务的区别: 宏任务:dom渲染后触发 微任务:dom渲染前触发 js代码的执行顺序 js是单线程的,而且dom渲染共用一个线程 第1轮宏任务(all同步代码,包括异步函数与promise) ->
  • Thread.Sleep()是同步延迟,Task.Delay()是异步延迟。 Thread.Sleep()会阻塞线程,Task.Delay()不会。 Thread.Sleep()不能取消,Task.Delay()... Task.Delay()Thread.Sleep()最大的区别是Task.Delay()旨在异步
  • BOM(二)

    2021-03-09 09:03:51
    (2)同步和异步 同步:前一个任务执行完执行下一个任务 异步:任务同时进行 本质区别:流水线上各个流程的执行顺序不同 ① 同步任务 同步任务都在主线程上执行,形成一个执行栈 ② 异步任务 JS的异步是通过回调函数...
  • Webpack高级配置(二)

    2020-08-22 23:12:27
    Webpack高级配置(二)一....异步则放入定时器定时器的import返回promise 二.解析vue 下载vue-loader插件然后 三.module chunk bundle的区别 import()就是上面的懒加载 一个chunk对应一个bundle ...
  • 前端面试题中的 for循环 + setTimeout

    千次阅读 2018-03-06 14:25:51
    js 定时器笔试题 分析以下代码实际运行的结果: for (var i = 0; i < 5; i++) { setTimeout(function() { ...JS 中同步和异步代码的区别、变量作用域、闭包等概念有正确的理解,就应该知道上面代码的...
  • immediate">setTimeout setImmediate 的区别</a></h5> </li><li> <h5><a href="#nexttick">process.nextTick()</a></h5> </li><li> <h5><a href="#nexttick&immediate">process.nextTick() setImmediate()...
  • 包括带时钟的同步通信不带时钟的异步通信,以及STM32的串口通信接口:UART异步通信方式的特点。还有中断优先级的分组,抢占/响应优先级的区别,以及中断函数的初始化。 (2)学习通用定时器的工作过程、PWM输出...
  • 看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一....1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 ...1)ReentrantLocksynchronized关键字的区别 41
  • 读核感悟 kbuild系统 编译到内核编译成模块的区别 24 读核感悟 kbuild系统 make bzImage的过程 26 读核感悟 kbuild系统 make menuconfig 31 读核感悟 文件系统 用C来实现面向对象 32 读核感悟 设计模式 用C来实现...
  • 02 并发并行与同步异步的概念 03 GIL的概念 04 同步锁 05 递归锁 06 同步对象event 07 信号量 08 线程队列 09 生产者消费者模型 10 多进程的调用 第35章 01 进程通信 02 进程池 03 协程 04 事件驱动模型 05 IO模型...
  •  nandnor的区别 103  设置文件系统区 103  性能优化 103  性能优化的需求 103  显示过程的优化 103  资源载入的优化 103 开发注意事项 104  如何在模拟上调试唤醒挂起 104  如何让系统不进入休眠...
  •  nandnor的区别 103  设置文件系统区 103  性能优化 103  性能优化的需求 103  显示过程的优化 103  资源载入的优化 103 开发注意事项 104  如何在模拟上调试唤醒挂起 104  如何让系统不进入休眠...
  • Linux内核阅读

    2012-03-08 14:39:32
    读核感悟-kbuild系统-编译到内核编译成模块的区别...........................24 读核感悟-kbuild系统-make bzImage的过程.....................................26 读核感悟-kbuild系统-make menuconfig............
  • 【web】异步请求 AsyncContext方式 Callable WebAsyncTask DeferredResult 220-web-sse 【web】sse 服务器发送事件 SseEmitter 221-web-resttemplate 【web】RestTemplate使用姿势 RestTemplate 222-web-...
  • 但是实施方案上面有轻量重量解决方案的区别,类似当年EJBSpring之争。 基于ESB、SOAP、WSDL等重型解决方案,演化出来SOA。 利用Dubbo、zookeeper、http/rest、consul、Eureka这些框架的轻量解决...
  • powerbuilder

    2013-11-21 17:11:48
    需要注意的是,在Windows95Windows NT 3.51以后的版本中,使用PrintSetup()函数设置的打印机设置只对当前应用起作用,并不影响其它应用的打印机设置。对Windows 3.1来说,使用PrintSetup()函数设置的打印机设置...
  • :honeybee:我们坚持每周为你提供高质量的关于小程序、h5 等前端领域的文章项目:sparkles:。 欢迎参与 ​ 如果你有兴趣参与,可以把发现的有价值的信息、文章等在Issues里提给我们,记得写上推荐的理由哈,我们...
  • 定时器或者window.requestAnimationFrame定时重复以上两步即可 二、抢金币核心原理 想象一下整个业务场景,我们先梳理出3个要解决的核心问题: 1、生成红包,这里有两种解决方案 * 1、统一生成...
  • ES6异步发送AJAX

    2021-02-20 00:41:44
    ES6异步发送AJAX 异步同步区别 同步:在上一个操作没有执行完前,下一个操作必须排队等待 异步:CPU先把当前操作耽搁不执行,等主线...js 中的核心异步执行函数是定时器和ajax setTimeout(console.log, 0, 1);

空空如也

空空如也

1 2
收藏数 29
精华内容 11
关键字:

同步定时器和异步定时器区别