javascript中的同步和异步

javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。

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

最基础的异步是setTimeout和setInterval函数,很常见,其实这就是异步;

示例:

<script>
        console.log( "1" );
        setTimeout(function() {
            console.log( "2" )
        }, 0 );
        setTimeout(function() {
            console.log( "3" )
        }, 0 );
        setTimeout(function() {
            console.log( "4" )
        }, 0 );
        console.log( "5" );
</script>

执行结果:

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

那么为什么呢?

是因为js代码执行是一个单线程操作,而浏览器是多线程的,当遇到引用数据类型的时候,会把这个数据放到一个任务队列中去执行,可以参照这张图理解浏览器工作编译

队列是什么呢?

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念——任务队列。

队列将一些耗时的代码(引用数据)操作排序在里面执行,在执行程序的时候,浏览器会默认将setTimeout、function以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),将其加入一个队列中,该队列是一个存储耗时程序的队列,在所有不耗时程序执行过后,再来依次执行该队列中的程序。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。于是JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。

于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。
只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

### JavaScript 同步异步的区别及使用场景 JavaScript 中的同步异步是两种不同的代码执行方式,它们各自适用于不同的场景。以下是两者的详细对比及使用场景: #### 1. 同步代码 同步代码按照顺序逐行执行,每行代码必须等待前一行代码完成后再继续执行。这种方式简单直观,但在处理耗时任务时可能会导致阻塞,影响程序性能。 示例: ```javascript const name = "Miriam"; const greeting = `Hello, my name is ${name}!`; console.log(greeting); // 输出: Hello, my name is Miriam! ``` 上述代码展示了同步代码的基本特点:每一行代码依次执行,直到所有代码完成[^2]。 #### 2. 异步代码 异步代码通过非阻塞的方式处理任务,允许程序在等待某些耗时操作(如网络请求、文件读取等)的同时继续执行其他任务。这种机制可以显著提升程序性能,避免因阻塞导致的用户体验下降。 异步代码的主要实现方式包括以下几种: - **回调函数**:将一个函数作为参数传递给另一个函数,在耗时任务完成后调用该函数。 - **Promise**:一种更优雅的异步处理方式,支持链式调用错误处理。 - **async/await**:基于 Promise 的语法糖,使异步代码看起来像同步代码,便于阅读维护。 示例(使用 `async/await`): ```javascript async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); } catch (error) { console.error('Error fetching data:', error); } } fetchData(); ``` 在此示例中,`fetch` 是一个异步操作,使用 `async/await` 可以让代码更加简洁且易于理解[^1]。 #### 使用场景 - **同步代码**:适用于简单的、不涉及耗时任务的场景,例如变量赋值、基本运算等。 - **异步代码**:适用于需要处理耗时任务的场景,例如网络请求、定时器、文件读写等。通过异步机制,可以让程序在等待这些任务完成的同时继续执行其他逻辑,从而提高性能[^3]。 #### 错误处理 需要注意的是,异步代码中的错误处理相对复杂。例如,使用回调函数时需要手动检查错误;使用 Promise 时可以通过 `.catch()` 方法捕获错误;而在 `async/await` 中则需要结合 `try...catch` 块来处理异常[^3]。 ### 结论 同步异步代码各有优劣,选择合适的方式取决于具体的应用场景。掌握事件循环、回调、Promise async/await 是编写高效 JavaScript 程序的关键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值