Promise,async,事件loop

本文详细探讨了JavaScript中的异步编程概念,包括window.onload、async/await、Promise、setTimeout、Promise.all等关键机制的工作原理及执行顺序。通过具体示例阐述了宏任务与微任务的区别,以及它们如何影响代码的执行流程。

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

window.οnlοad=function(){
}
页面中所有的元素加载完成后所执行的函数(所有DOM加载完成,CSS样式应用,图片加载完成后)
逐条执行(head—link,(css)同步------- script标签(同步)-----执行script-------》body------》img(video,audio)异步完成--------》完成所有DOM加载---------》link的CSS应用给DOM元素-----》所有内容完成)

async

异步函数,返回一个Promise
异步加载,不再等待加载完成后再执行下个标签。
如果加载时,使用async,就不能再加载其他
图片加载时异步
defer所有内容加载完成后。
(脚本加载拥塞会造成图片和link停止加载,不会恢复link和图片的加载)

Promise

let a=0;
let pro=new Promise(promiseHandler)
function promiseHandler(resolve,reject){
if(a>0){
resolve();
}else{
reject();
}
}
两个 参数
resolve:成功时执行的语句
reject:失败时执行的语句
手写:

  class Promises {
        constructor(fn) {
            this.state = "pending";
            fn(this.resolve.bind(this), this.reject.bind(this))
        }
        resolve(value) {
            if (this.state !== "pending") return;
            this.state = "resolve";
           let ids= setTimeout(() => {
                this.fn1(value);
                clearTimeout(ids);
            });
        }
        reject(value) {
            if (this.state !== "pending") return;
            this.state = "reject";
            let ids= setTimeout(() => {
                this.fn2(value);
                clearTimeout(ids);
            })
        }
        then1(fn1, fn2) {
            this.fn1=fn1;
            this.fn2 = fn2;
        }
        catch1(fn2){
            this.fn2=fn2;
        }
    }
    console.log("aaa");
    new Promises(function (resolve, resject) {
        resolve("a");
        resject("d");
        console.log("bbb");
    }).then1(function (a) {
        console.log(a);
    }, function (b) {
        console.log(b);
    })

在这里插入图片描述
一个一个加载
在这里插入图片描述

Promise.all静态方法
所有的异步完成后
在这里插入图片描述

在这里插入图片描述

await:将异步转换为同步等待
必须在async函数中,
可以让某个异步先完成后,再继续同步执行后面的,包括循环。

事件loop

let定义的变量限于花括号内部
var 循环体外
在这里插入图片描述
事件抛发的先后顺序
抛发时是同步的,什么时候抛发就什么时候执行。
加载的先后顺序(load)
js当前的同步加载完后再执行

所有的异步是在同步完成后执行的
三种异步{
load(error)
宏任务(setTimeOut,setInterval)(下一个任务列的最顶端)
微任务(Promise, async, await) (当前任务列的最低端,----最后执行)
}
在同一任务列中 先宏再微
整个任务序列流中,先微再宏(当前任务完成再执行下一个任务)
new promise是同步执行,then下面的是异步执行

setTimeOut比promise 下面的setTimeout要早
宏任务下面的微任务,要比宏任务早
并行的两个微任务,上一个微任务完成后,执行下一个。
微任务里的微任务优先于当前的异步

134652
在这里插入图片描述

1,2,18,19,3,5,4,9,10,11,17,20,13,12,6,7,16,8,15,14,

console.log(1);
new Promise(function (res,rej) {
    console.log(2);
    res();
}).then(function () {
    console.log(3);
    Promise.resolve().then(function () {
        console.log(5);
        setTimeout(function () {
           console.log(6);
           Promise.resolve().then(function () {
               console.log(7);
           });
           setTimeout(function () {
               console.log(8)
           },0);
        },0)
    })
}).then(function () {
    console.log(4);
});
setTimeout(function () {
    console.log(9);
    new Promise(function (res) {
        res();
        console.log(10);
    }).then(function () {
        console.log(11);
    })
});
Promise.resolve().then(function () {
    setTimeout(function () {
       Promise.resolve().then(function () {
           console.log(12);
       });
        console.log(13);
    },0)
});
setTimeout(function () {
    setTimeout(function () {
        setTimeout(function () {
            Promise.resolve().then(function () {
                console.log(14);
            });
            console.log(15);
        });
        console.log(16);
    });
    console.log(17);
});
console.log(18);
new Promise(function (res) {
    console.log(19);
    setTimeout(function () {
       console.log(20);
    },0)
})

321
在这里插入图片描述

 <script>
           console.log(111)
          setTimeout(function(){
           console.log(555);
           new Promise(function(resolve,reject){
           console.log(666)
             resolve()
        }).then(function(){
            console.log(777)

        })
        },0)
        

        new Promise(function(resolve,reject){
        console.log(222)
        resolve()
        }).then(function(){
        console.log(444)
        })    
        console.log(333)
        
    </script>
JavaScript 中的 `Promise`、`async` 和 `await` 是处理异步操作的核心机制,它们的执行顺序和原理与 JavaScript 的事件循环(Event Loop)和微任务队列(Microtask Queue)密切相关。理解这些机制有助于编写高效、可维护的异步代码。 ### 事件循环与任务队列 JavaScript 的主线程是单线程的,所有任务都在主线程上按顺序执行。异步操作不会阻塞主线程,而是通过事件循环机制处理。任务分为宏任务(Macrotask)和微任务(Microtask)两类: - **宏任务**:如 `setTimeout`、`setInterval`、`I/O` 操作等。 - **微任务**:如 `Promise.then`、`MutationObserver`、`queueMicrotask` 等。 微任务的优先级高于宏任务,在每次宏任务执行完毕后,事件循环会优先清空微任务队列。 ### Promise 的执行顺序 `Promise` 是异步编程的基础,其 `then` 和 `catch` 方法会在当前执行栈清空后,被放入微任务队列中执行。例如: ```javascript console.log("Start"); Promise.resolve().then(() => { console.log("Promise 1"); }); console.log("End"); // 输出顺序: // Start // End // Promise 1 ``` 在上述代码中,`Promise.then` 被推入微任务队列,并在同步代码执行完毕后才执行。 ### async/await 的执行顺序 `async` 函数会返回一个 `Promise` 对象,函数内部可以使用 `await` 关键字等待异步操作完成。`await` 会暂停当前 `async` 函数的执行,直到右侧的 `Promise` 解决(resolve)或拒绝(reject)。 ```javascript async function asyncFunc() { console.log("Start async"); await Promise.resolve(); console.log("End async"); } console.log("Before async"); asyncFunc(); console.log("After async"); // 输出顺序: // Before async // Start async // After async // End async ``` 在这个例子中,`await Promise.resolve()` 将 `console.log("End async")` 推入微任务队列,因此它在同步代码执行完毕后才执行。 ### 综合示例 结合 `setTimeout`、`Promise`、`async/await`,可以更清楚地理解它们的执行顺序: ```javascript console.log("script start"); setTimeout(() => { console.log("setTimeout"); }, 0); Promise.resolve().then(() => { console.log("Promise then"); }); async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } async1(); console.log("script end"); // 输出顺序: // script start // async1 start // async2 // script end // Promise then // async1 end // setTimeout ``` 在这个示例中: - `async1()` 被调用,`async1 start` 和 `async2` 是同步执行的。 - `await async2()` 之后的代码(`async1 end`)被放入微任务队列。 - `Promise.then` 也被放入微任务队列。 - 最后,`setTimeout` 作为宏任务被放入任务队列,在微任务队列清空后执行。 ### 原理总结 - `Promise` 的 `.then` 回调会被放入微任务队列中,在当前宏任务结束后执行。 - `await` 会将后续代码(即 `await` 之后的语句)放入微任务队列。 - 微任务优先于宏任务执行,因此 `Promise.then` 和 `await` 后续代码会在下一个宏任务之前执行。 这些机制确保了异步操作的可预测性和一致性,同时避免了阻塞主线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值