Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript >_Javascript_Jquery - Fatal编程技术网

Javascript >

Javascript >,javascript,jquery,Javascript,Jquery,JS的代码执行方式是同步的。每一行只在它完成之前在该行之后运行,如果该行在该行完成之后调用函数,等等 主要的混淆点来自这样一个事实:您的浏览器能够告诉JS在任何时候执行更多的代码(类似于您如何从控制台在页面上执行更多的JS代码)。例如,JS具有回调函数,其目的是允许JS异步运行,以便在等待已执行的JS函数(即GETcall)返回应答时,JS的其他部分可以运行,JS将继续运行,直到浏览器在该点有应答事件循环(浏览器)将执行调用回调函数的JS代码 由于事件循环(浏览器)可以输入更多的JS以在任何时候

JS的代码执行方式是同步的。每一行只在它完成之前在该行之后运行,如果该行在该行完成之后调用函数,等等

主要的混淆点来自这样一个事实:您的浏览器能够告诉JS在任何时候执行更多的代码(类似于您如何从控制台在页面上执行更多的JS代码)。例如,JS具有回调函数,其目的是允许JS异步运行,以便在等待已执行的JS函数(即
GET
call)返回应答时,JS的其他部分可以运行,JS将继续运行,直到浏览器在该点有应答事件循环(浏览器)将执行调用回调函数的JS代码

由于事件循环(浏览器)可以输入更多的JS以在任何时候执行,因此JS是异步的(导致浏览器输入JS代码的主要因素是超时、回调和事件)

我希望这足够清楚,能够对某人有所帮助。

定义 术语“异步”的含义可能稍有不同,导致此处的答案看似矛盾,但实际上并非如此。有这样的定义:

在计算机编程中,异步是指独立于主程序流和处理此类事件的方法的事件的发生。这些可能是“外部”事件,如信号的到达,或由程序发起的与程序执行同时发生的动作,而程序不阻塞等待结果

非JavaScript代码可以将此类“外部”事件排队到一些JavaScript事件队列。但这就是问题的症结所在

不可抢先 为了在脚本中执行其他一些JavaScript代码,运行JavaScript代码时没有外部中断。JavaScript片段一个接一个地执行,顺序由每个事件队列中事件的顺序以及这些队列的优先级决定

例如,您可以绝对确保在执行以下代码时不会执行任何其他JavaScript(在同一脚本中):

let a = [1, 4, 15, 7, 2];
let sum = 0;
for (let i = 0; i < a.length; i++) {
    sum += a[i];
}
a=[1,4,15,7,2];
设和=0;
for(设i=0;i
换言之,JavaScript中不存在任何错误。无论事件队列中有什么,这些事件的处理都必须等到这段代码运行完成。EcmaScript规范在中说明:

只有在没有运行的执行上下文且执行上下文堆栈为空时,才能启动作业的执行

异步示例 正如其他人已经写过的,有几种情况下,异步在JavaScript中发挥作用,它总是涉及一个事件队列,只有在没有其他JavaScript代码执行时,才会导致JavaScript执行:

let a = [1, 4, 15, 7, 2];
let sum = 0;
for (let i = 0; i < a.length; i++) {
    sum += a[i];
}
  • setTimeout()
    :当超时过期时,代理(例如浏览器)将事件放入事件队列。对时间的监控和事件在队列中的放置是由非JavaScript代码完成的,因此您可以想象这与一些JavaScript代码的潜在执行并行进行。但是提供给
    setTimeout
    的回调只能在当前执行的JavaScript代码运行到完成并且正在读取相应的事件队列时执行

  • fetch()
    :代理将使用OS函数执行HTTP请求并监视任何传入响应。同样,这个非JavaScript任务可能与一些仍在执行的JavaScript代码并行运行。但是承诺解析过程将解析
    fetch()
    返回的承诺,它只能在当前执行的JavaScript运行到完成时执行

  • requestAnimationFrame()
    :当浏览器的渲染引擎(非JavaScript)准备执行绘制操作时,它将在JavaScript队列中放置一个事件。处理JavaScript事件时,将执行回调函数

  • queueMicrotask()
    :立即在微任务队列中放置事件。当调用堆栈为空且该事件已被使用时,将执行回调

还有更多的示例,但所有这些函数都是由主机环境提供的,而不是由核心EcmaScript提供的。使用core EcmaScript,您可以使用
Promise.resolve()
将事件同步放置在承诺作业队列中

语言结构 EcmaScript提供了几种支持异步模式的语言构造,如
yield
async
wait
。但是不要搞错:没有JavaScript代码会被外部事件中断。
yield
await
似乎提供的“中断”只是一种受控的预定义方式,用于从函数调用返回并稍后通过JS代码(在
yield
的情况下)或事件队列(在
await
的情况下)恢复其执行上下文

DOM事件处理 当JavaScript代码访问DOM API时,在某些情况下可能会使DOM API触发一个或多个同步通知。如果您的代码有一个事件处理程序监听该消息,则将调用它

这可能会被认为是先发制人的并发,但事实并非如此:一旦事件处理程序返回,domapi最终也将返回,原始JavaScript代码将继续

在其他情况下,domapi将只在适当的事件队列中调度一个事件,JavaScript将在调用堆栈清空后拾取它


请参见

在所有情况下都是同步的

使用
承诺
阻塞线程的示例:

const test=()=>新承诺((结果,拒绝)=>{
常量时间=新日期().getTime()+(3*1000);
console.info('teststart…');
<html>
    <head>

    </head>
    <body>

        <script src="program.js"></script>
    </body>
</html>
waitfunction() context will be popped after this line
global context will be emptied after this line
click event handler...
let a = [1, 4, 15, 7, 2];
let sum = 0;
for (let i = 0; i < a.length; i++) {
    sum += a[i];
}
Test start...
Test finish...
Finish!
         A-Start ------------------------------------------ A-End   
           | B-Start -----------------------------------------|--- B-End   
           |    |      C-Start ------------------- C-End      |      |   
           |    |       |                           |         |      |
           V    V       V                           V         V      V      
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->|