首页 > 科普大全

「单线程」js延迟1秒的方法(javascript延时函数)

科普大全 2023-09-05 02:08:01
今天小编给各位分享「单线程」js延迟1秒的方法(javascript延时函数),如果能碰巧解决你现在面临的问题,别忘了关注小站,我们一起开始吧!

「单线程」js延迟1秒的方法(javascript延时函数)

很多朋友不太了解js延迟1秒的方法(javascript延迟函数)。今天,我将通过边肖与你分享,希望对你有所帮助。我们来看看吧!全文预计阅读时间为3分钟。

异步的

简单来说,JavaScript是单线程语言,但是在使用中有很多异步执行的情况。异步的本质是以其他方式(相对同步)控制程序的执行顺序,这与其他语言中的多线程模型不同,所以人们常常对非顺序JavaScript代码的运行结果感到困惑。

一个简单的小程序

任何使用过JavaScript的程序员都可以说出以下代码的输出:

("A");setTimeout(() => { ("B");}, 100);("C");

顺序是A、C和B,因为第二个参数用于指定延迟的毫秒数。这段代码只有一个setTimeout,所以不会混淆。

类似程序的解释通常是setTimeout设置一个定时器,在指定的毫秒数后调用回调函数。然而,它的实现机制并不那么简单。实际上,setTimeout的功能是在给定机会时,在指定的毫秒数之后,将回调放入事件循环队列。

事件循环

首先要抛出一些概念。JavaScript引擎通常指的是负责一个接一个执行程序块的程序。它取决于主机环境的调度,需要与操作系统相关联,并通过主机环境得到支持。JavaScript引擎是JavaScript运行时(托管环境)的一部分。

每个块通常以函数为单位,直到完成一个块才会执行下一个块。下一块是什么?这取决于当前事件循环队列中的队列头。事件循环队列中充满了消息,每条消息都与一个函数相关联,JavaScript引擎按照队列中消息的顺序执行它们,也就是执行chunk。

所以上面的setTimeout实际上更接近于这个:

Chunk1执行:定时器由setTimeout (100ms)启动。chunk2执行:当机会出现时,将回调放入事件循环队列chunk3执行:此回调执行。

不难发现,获得机会很重要!这也解释了用setTimeout延迟1000不一定准确,但至少会延迟一秒。因为如果前面有其他任务,它必须等待与这些任务相对应的消息出队,也就是说,程序都被执行,然后才能将回调放入队列。也就是说,实际延迟将大于或等于一秒。

当事件被触发时,意味着事件监听器已经被执行。与setTimeout示例中的概念一样,这也是一个块执行。像这样一个一个执行chunk的过程叫做事件循环。

另一个经常提到的概念是“非阻塞”,JavaScript中的非阻塞指的就是这种事件循环模型。除了告警或同步Ajax请求等历史原因,程序永远不会阻塞;也就是说,JavaScript引擎总能处理下一个任务,比如处理用户在浏览器上的操作。

一些简单的小例子

如果在try语句中加入setTimeout会怎么样?

try { setTimeout(() => { throw new Error("Error - from try statement"); }, 0);} catch (e) { (e);}

Try catch和setTimeout不在同一个块中,因此...你知道的。

看下一个。

下面的堆栈信息会输出为C–B–A吗?

setTimeout(function A() { setTimeout(function B() { setTimeout(function C() { throw new Error("Error - from function C"); }, 0); }, 0);}, 0);

它们并不对应同一个事件循环队列中的消息,它们有自己的调用栈,所以错误栈中只有C。

作业队列

Job是ES6中的新概念,与承诺的执行有关,可以理解为等待执行的任务。作业队列是这类任务的队列。JavaScript运行时以不同的方式处理作业队列和事件循环队列。

相似之处:

用作先进先出队列

差异:

每个JavaScript运行时可以有多个作业队列,但只有一个事件循环队列。当JavaScript引擎处理完当前块时,将首先执行所有作业队列,然后处理事件循环队列。

在ES6中,一个承诺就是一份承诺,一份工作。

我们来观察一个小程序:

("A");setTimeout(() => { ("A - setTimeout");}, 0);new Promise((resolve) => { resolve();}).then(() => { return ("A - Promise 1");}).then(() => { return ("B - Promise 1");});new Promise((resolve) => { resolve();}).then(() => { return ("A - Promise 2");}).then(() => { return ("B - Promise 2");}).t**粗体文字**hen(() => { return ("C - Promise 2");});("AA");

在本机支持Promise的环境中,输出如下所示:

A

嗜酒者互诫协会

承诺1

承诺2

b–承诺1

承诺2

承诺2

a–设置超时

理解这个输出:

首先输出a和AA,因为它们不是异步任务,属于第一个chunk。Promise 1和Promise 2在setTimeout之前执行,因为作业队列的执行优先于事件循环队列。Promise 1和Promise 2的输出是顺序的,因为作业队列是先进先出队列,同一作业队列中的任务是顺序执行的。承诺1和承诺2的后续任务是错开的,因为承诺1和承诺2都是独立的承诺作业(作业之一),属于不同的作业队列,规范中没有规定它们之间的顺序。被...复杂化

文章开头我说过,“简单来说,JavaScript是单线程语言。”现在可以说的复杂一点:JavaScript引擎在JavaScript程序的执行上是单线程的,但是JavaScript运行时(整个主机环境)不是单线程的;而且几乎所有的异步任务都是并发的,比如多任务队列、Ajax、Timer、I/O(Node)等等。

上面说的是JavaScript运行时级别,JavaScript执行本身,还有一些特殊情况,比如:一个Web Worker或者跨域的iframe,它也是一个独立的线程,有自己的内存空间(栈,堆)和事件循环队列。要与这些不同的线程通信,只能使用postMessage。postMessage将消息添加到另一个线程的事件循环队列中。

参考数据

并发模型和事件循环

ECMAScript 2015语言规范

你不知道JS:Async & amp;表演

JavaScript异步编程:设计快速响应网络应用程序

js延迟1秒的方法(javascript delay函数)说明到此结束。更多相关信息,可以继续在本网站查找。感谢您的阅读!


标签: 函数   方法   延迟   单线

生活百科 饮食百科 健康养生 美容减肥 自然百科 科普大全 文化常识
Copyright 百科网 备案号:冀ICP备2022029337号-3本站图文信息均来自于网络收集,仅供大家参考,不作为医疗诊断依据。
统计代码