JS几种同步和异步

本文深入探讨JavaScript中的同步执行和异步执行概念,包括回调函数、Promise和async/await等异步处理方式,帮助开发者理解如何在JavaScript环境中有效地管理代码执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

同步和异步

同步
    (1)
    var a=3;
    var b=4;
    console.log(b);
    var c=a+b;
    console.log(c);
    for(var i=0;i<10000;i++){
        c+=i;
    }
    console.log(c);
    按照顺序依次打印b,c,c,同步
    (2)
    function fn1(fn){
        console.log("a");
        fn();
    }
    function fn2(){
        console.log("b");
    }
    fn1(fn2);
    执行fn1,先打印a,再执行fn2,打印b,同步
    (3)
    console.log("a");
    document.addEventListener("abc",abcHandler);
    console.log("b");
    var evt=new Event("abc");
    document.dispatchEvent(evt);
    console.log("d");
    function abcHandler(e){
        console.log("c");
    }
    先打印a,b,然后抛发事件后执行函数,打印c,再打印d,同步
    
异步
    (1)
    console.log("a");
    setTimeout(function(){
        console.log("b");
    },0)
    console.log("c");
    打印a,c,b。0毫秒以后执行,代表执行完所有代码后的0毫秒,执行。异步

    (2)load,error事件
    console.log("a");
    var img=new Image();
    img.addEventListener("load",loadHandler);
    img.src="./img/3.jpg";
    console.log("c");
    function loadHandler(e){
        console.log("b");
    }
    先打印,a,c,加载完成后打印b。异步
    console.log("a");
    var img=new Image();
    img.addEventListener("error",loadHandler);
    img.src="./img/3.jpg";
    console.log("c");

    function loadHandler(e){
        console.log("b");
    } 
    当加载的图片不存在时,会报错,此时已经打印了a,b,再打印c。异步

当导入外部js文件时
    1.
    <script src="./js/a.js" ></script>
    <script src="./js/b.js" ></script>
    如果直接加载js文件,首先加载第一文件,并且执行这个js所有代码,完成后再加载第二文件,然后再执行里面的代码,这种情况也是同步。
    2.
    但是由于同步阻塞会造成浏览器显示问题,所以将其改为异步:
    <script src="./js/a.js" async></script>
    <script src="./js/b.js" async></script>
    添加async后,导入js文件的过程就为异步过程了。
    3.
    由于都添加了async,导入顺序错乱,可以在async后面添加defer,让其最后执行
    <script src="./js/a.js" async></script>
    <script src="./js/b.js" async defer></script>
### JavaScript 实现异步操作的方法 #### 回调函数 回调函数是一种常见的实现异步操作的方式。当某个耗时任务完成时,会自动触发该回调函数的执行。这种方式虽然简单易懂,但在多个异步任务嵌套的情况下容易形成“回调地狱”,使得代码难以维护阅读[^1]。 #### Promise 对象 为了改善回调函数带来的问题,ES6 引入了 `Promise` 对象。它代表了一个异步操作的最终完成(或失败),并允许关联成功或失败后的处理逻辑。通过链式调用 `.then()` `.catch()` 方法可以更优雅地管理异步流程。 ```javascript const promiseExample = new Promise((resolve, reject) => { setTimeout(() => resolve('Success!'), 1000); }); promiseExample.then(message => console.log(message)).catch(error => console.error(error)); ``` #### Async/Await 关键字 随着 ES8 的发布,JavaScript 提供了一种更加简洁直观的方式来书写异步代码——async/await 结构。这不仅让开发者能够写出看起来像同步风格的异步代码,还简化了错误处理过程。使用 await 可以暂停当前函数直到对应的 Promise 被解决,同时不会阻塞整个应用程序的执行流。 ```javascript async function asyncAwaitExample() { try { let result = await someAsyncFunction(); console.log(result); // 处理返回的结果 } catch (error) { console.error(error); // 错误捕获 } } ``` #### 宏任务与微任务队列 理解宏任务(Macro-task)微任务(Micro-task)对于掌握 JavaScript 的事件循环至关重要。每次遇到异步操作时,浏览器都会将其放入相应的任务队列中等待执行。一旦当前的任务栈清空,则依次从这两个队列里取出待办事项继续推进程序进展。值得注意的是,所有的 micro-tasks 都会在下一个 macro-task 开始之前被执行完毕[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值