promise、setTimeout、async的先后执行顺序

执行顺序:先执行同步代码,遇到异步代码就先加入队列,然后按入队顺序执行异步代码,最后执行setTimeout队列的代码

setTimeout的任务队列优先级低于promise队列,setTimeout的队列与promise不是一个队列

例子

setTimeout(function(){
        console.log('2');
                    
},0);
                
let promise = new Promise(function(resolve, reject) {
               console.log('3');
                resolve();
          }).then(function(){
               console.log('resolve3');
          }).then(function(){
                console.log('reject3')
     });
console.log('4');

执行结果是:3,4,resolve3,reject3,2

从规范上来讲,setTimeout有一个4ms的最短时间,也就是说不管你设定多少,反正最少都要间隔4ms才运行里面的回调。而Promise的异步没有这个问题。

创建Promise实例是同步执行的,所以会先输出3,4

promise.then与setTimeout都是异步执行的,会先执行promise.then

 

例:

async function async1() {           
                     console.log("async1 start");  //(2)        
                     await  async2();            
                     console.log("async1 end");   //(7)    
                 }        
                 async  function async2() {          
                     console.log( 'async2');   //(3)     
                 }       
                 console.log("script start");  //(1)      
                 setTimeout(function () {            
                     console.log("settimeout");  //(8)      
                 },0);        
                 async1();        
                 new Promise(function (resolve) {           
                     console.log("promise1");   //(4)         
                     resolve();        
                 }).then(function () {            
                     console.log("promise2");    //(6)    
                 });        
                 console.log('script end');//(5)

 

 

先按顺序执行同步代码  从‘script start‘开始,

执行到setTimeout函数时,将其回调函数加入队列(此队列与promise队列不是同一个队列,执行的优先级低于promise)。

然后调用async1()方法,await async2();//执行这一句后,输出async2后,await会让出当前线程,将后面的代码加到任务队列中,然后继续执行test()函数后面的同步代码

继续执行创建promise对象里面的代码属于同步代码,promise的异步性体现在then与catch处,所以promise1被输出,然后将then函数的代码加入队列,继续执行同步代码,输出script end。至此同步代码执行完毕。

开始从队列中调取任务执行,由于刚刚提到过,setTimeout的任务队列优先级低于promise队列,所以首先执行promise队列的第一个任务,因为在async函数中有await表达式,会使async函数暂停执行,等待表达式中的 Promise 解析完成后继续执行 async 函数并返回解决结果。

所以先执行then方法的部分,输出promise2,然后执行async1中await后面的代码,输出async1 end。。最后promise队列中任务执行完毕,再执行setTimeout的任务队列,输出settimeout。

setTimeout(fn,0)的含义是指某个任务在主线程最早可得的空闲时间执行。它在“任务队列”的尾部添加一个事件,因此要等到同步任务和“任务队列”现有的时间处理完才会得到执行。

转载于:https://www.cnblogs.com/xiaoan0705/p/10451360.html

Promise是一种用于处理异步操作的特殊对象。它表示一个尚未完成但最终会完成的操作,并可以用于处理回调地狱和编写更清晰、更可读的异步代码。一个Promise对象有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一旦Promise的状态变为fulfilled或rejected,它就被认为是已解决(settled)。 创建Promise对象时,我们可以通过传递一个执行器函数来定义异步操作。执行器函数接受两个参数:resolve和reject。当异步操作成功时,我们可以调用resolve函数将Promise的状态设置为fulfilled,并传递解决值。当异步操作失败时,我们可以调用reject函数将Promise的状态设置为rejected,并传递错误信息。 下面是一个使用Promise的简单示例: ```javascript const myPromise = new Promise((resolve, reject) => { // 异步操作 setTimeout(() => { const randomNumber = Math.random(); if (randomNumber > 0.5) { resolve(randomNumber); } else { reject('Number is less than 0.5'); } }, 1000); }); // 使用then()方法处理Promise的解决结果 myPromise.then((result) => { console.log('Resolved:', result); }).catch((error) => { console.log('Rejected:', error); }); ``` 上面的代码创建了一个Promise对象,其中包含一个延迟1秒的异步操作。如果生成的随机数大于0.5,则调用resolve函数解决Promise,否则调用reject函数拒绝Promise。然后,我们使用then()方法处理Promise的解决结果,catch()方法处理Promise的拒绝结果。 在ES2017中,引入了async/await关键字,它们是使用Promise的语法糖,可以更简洁地处理异步操作。 async函数是一个返回Promise的函数,它使用async关键字声明。在async函数中,我们可以使用await关键字来等待一个Promise解决,并返回解决值。使用async/await可以将异步代码写成类似于同步代码的形式,使其更易读和理解。 下面是一个使用async/await的示例: ```javascript function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } async function myAsyncFunction() { try { console.log('Start'); await delay(1000); console.log('After 1 second'); await delay(2000); console.log('After 2 seconds'); } catch (error) { console.log('Error:', error); } } myAsyncFunction(); ``` 上面的代码定义了一个async函数`myAsyncFunction()`,其中使用了await关键字等待两个延迟操作的Promise解决。通过使用try-catch块,我们可以捕获可能出现的错误。 当我们调用`myAsyncFunction()`时,它会被执行,并按顺序打印出"Start"、"After 1 second"和"After 2 seconds"。由于async函数返回一个Promise,我们也可以使用then()和catch()方法来处理解决和拒绝结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值