函数

// 你不能改变一个函数的 name 属性的值, 因为该属性是只读的
var object = {
// someMethod 属性指向一个匿名函数
someMethod: function() { }
};
object.someMethod.name = "otherMethod";
console.log(object.someMethod.name); // someMethod 函数的length属性等于该函数声明时所要传入的新参数量
通过arguments.length,可以知道在调用时传入了多个参数

setTimeout()和setInterval()的区别

setTimeout(()=>{
console.log('执行setTimeout')
},1000)
setInterval(()=>{
console.log('执行setInterval')
},1000)
setTimeout是执行并延迟1s执行
只有满足 (1)3秒后 (2)主线程空闲,同时满足时,才会3秒后执行该函数
setInterval是每隔1s就尝试执行

setTimeout、setInterval被遗忘的第三个参数

for ( var i=1; i<=5; i++) {
setTimeout( function timer(j) {
console.log( j );
}, i*1000, i);
}
第三个参数param1,param2l...
作为参数传递给function或者字符串中的参数

event loop的概念

微任务 promise  process.nextTick
宏任务 setTimeout setInterval I/O script
同一次事件循环中 微任务永远在宏任务之前执行

 setTimeout(function(){
console.log('定时器开始啦')
}); new Promise(function(resolve){
console.log('马上执行for循环啦');
for(var i = 0; i < 10000; i++){
i == 99 && resolve();
}
}).then(function(){
console.log('执行then函数啦')
}); console.log('代码执行结束');
首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里

遇到 new Promise直接执行,打印"马上执行for循环啦"

遇到then方法,是微任务,将其放到微任务的【队列里】

打印 "代码执行结束"

本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数啦"

到此,本轮的event loop 全部完成。

下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"

【马上执行for循环啦 --- 代码执行结束 --- 执行then函数啦 --- 定时器开始啦】

async function fn1(){
return 123
} function fn2(){
return 123
} console.log(fn1())
console.log(fn2())
//返回
Promise {<resolved>: 123}
123
-----
new promise(()=>{
同步的
}).then(
异步的微任务
)

第二题

setTimeout(() => console.log('setTimeout1'), 0);  //1宏任务
setTimeout(() => { //2宏任务
console.log('setTimeout2');
Promise.resolve().then(() => {
console.log('promise3');
Promise.resolve().then(() => {
console.log('promise4');
})
console.log(5)
})
setTimeout(() => console.log('setTimeout4'), 0); //4宏任务
}, 0);
setTimeout(() => console.log('setTimeout3'), 0); //3宏任务
Promise.resolve().then(() => {//1微任务
console.log('promise1');
})

第三题

async function async1() {
console.log( 'async1 start' )
await async2()
console.log( 'async1 end' )
}
async function async2() {
console.log( 'async2' )
}
async1()
console.log( 'script start' ) 执行结果
async1 start
async2
script start
async1 end

一旦遇到await 就立刻让出线程,阻塞后面的代码

等候之后,对于await来说分两种情况

  • 不是promise 对象
  • 是promise对象

如果不是promise,await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完毕后,在回到async内部,把promise的东西,作为await表达式的结果

如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。

如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。

第四题

        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

控制台执行任何语句都认为是在一个匿名函数空间包裹下的,JS函数return; 和不写return都是默认返回undefined,所以会在控制台下输出undefined

第五题

       new Promise( ( resolve, reject ) => {
console.log( "promise1" )
resolve()
} )
.then( () => {
console.log( 1 )
} )
.then( () => {
console.log( 2 )
} )
.then( () => {
console.log( 3 )
} ) new Promise( ( resolve, reject ) => {
console.log( "promise2" )
resolve()
} )
.then( () => {
console.log( 4 )
} )
.then( () => {
console.log( 5 )
} )
.then( () => {
console.log( 6 )
} )
// 1 4 2 5 3 6

先执行同步代码 promise1, promise2,此时微任务有两个任务 log(1)和log(4)

执行完log(1)和log(4)此时任务中有log(2)和log(5)两个微任务

执行log(2)和log(5)此时任务中有log(3)和log(6)两个微任务

连续的几个then()回调,并不是连续的创建了一系列的微任务并推入微任务队列,因为then()的返回值必然是一个Promise,而后续的then()是上一步then()返回的Promise的回调

ECS(执行环境栈)

function foo(i) {
if (i < 0) return;
console.log('begin:' + i);
foo(i - 1);
console.log('end:' + i);
}
foo(2); // 输出: // begin:2
// begin:1
// begin:0
// end:0
// end:1
// end:2

**执行栈既是函数在执行时存储调用过程的栈,同样的,采取调用形式进行队列,先进后出的方式 **

第六题

async function t1 () {
console.log(1)
console.log(2)
await Promise.resolve().then(() => console.log('t1p'))
console.log(3)
console.log(4)
} async function t2() {
console.log(5)
console.log(6)
await Promise.resolve().then(() => console.log('t2p'))
console.log(7)
console.log(8)
} t1()
t2() console.log('end') // 输出:
// 1
// 2
// 5
// 6
// end
// t1p
// t2p
// 3
// 4
// 7
// 8
// undefined

第七题

async function t1 () {
console.log(1)
console.log(2)
await new Promise(resolve => {
setTimeout(() => {
console.log('t1p')
resolve()
}, 1000)
})
await console.log(3)
console.log(4)
} async function t2() {
console.log(5)
console.log(6)
await Promise.resolve().then(() => console.log('t2p'))
console.log(7)
console.log(8)
} t1()
t2() console.log('end') // 输出:
// 1
// 2
// 5
// 6
// end
// t2p
// 7
// 8
// undefined
// t1p
// 3
// 4

javascript宏任务和微任务的更多相关文章

  1. JavaScript的事件队列(Event Queue)---宏任务和微任务

    前言 在写代码的时候经常思考一个问题,到底是那个函数先执行,本身JavaScript是一门单线程的语言,意思就是按照顺序执行.但是加入一些setTimeout和promise的函数来又实现了异步操作, ...

  2. JavaScript同步模式,异步模式及宏任务,微任务队列

    首先JavaScript是单线程的语言,也就是说JS执行环境中,负责执行代码的线程只有一个.一次只能执行一个任务,如果有多个任务的话, 就要排队,然后依次执行,优点就是更安全,更简单.缺点就是遇到耗时 ...

  3. javascript中的宏任务和微任务(一)

    一.宏任务和微任务有哪些 宏任务:setTimeout,setInterval,ajax,dom,宏任务是由浏览器提供的 微任务:promise,async/await,微任务是由es6提供的 二.微 ...

  4. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

  5. Event Loop、 宏任务和微任务

    本文将介绍我自己对JS Event Loop 和 宏任务.微任务的理解. 二话不说先上图: 接下来将会针对此图讲解什么是Event Loop 什么事宏任务和微任务(其实聪明的你们通过图大体也能了解的是 ...

  6. JS中EventLoop、宏任务与微任务的个人理解

    为什么要EventLoop? JS 作为浏览器脚本语言,为了避免复杂的同步问题(例如用户操作事件以及操作DOM),这就决定了被设计成单线程语言,而且也将会一直保持是单线程的.而在单线程中若是遇到了耗时 ...

  7. 浏览器端时间循环与nodejs端时间循环的不同之处(宏任务与微任务)

    浏览器端与node端都有宏任务与微任务的概念.字面意思上看宏任务就是耗时间比较长的任务,而微任务是耗时短的任务. 在浏览器端,宏任务包括setTimeout,setInterval,微任务则包括Pro ...

  8. js中的宏任务与微任务

    如果你已经知道了js中存在宏任务和微任务,那么你一定已经了解过promise了.因为在js中promise是微任务的一个入口. 先来看一道题: setTimeout(function(){ conso ...

  9. 详解JavaScript的任务、微任务、队列以及代码执行顺序

    摘要: 理解JS的执行顺序. 作者:前端小智 原文:详解JavaScript的任务.微任务.队列以及代码执行顺序 思考下面 JavaScript 代码: console.log("scrip ...

随机推荐

  1. Confluence 6 升级自定义的站点和空间布局

    随着 Confluence 的演变.默认的站点和空间布局也会随着 Confluence 升级而让使用的所有页面进行改变.随着一些新功能的加入和一些老功能的修改,默认的布局也需要进行修改来支持这些改变. ...

  2. django 中session的存储和获取

  3. 初始Ajax

    一.Ajax准备知识:json 说起json,我们大家都了解,就是python中的json模块,那么json模块具体是什么呢?那我们现在详细的来说明一下 1.json(Javascript  Obie ...

  4. UEFI rootkit 工具LoJax可以感染电脑主板(mainboard)

    1.UEFI(Unified Extensible Firmware Interface)统一扩展接口,UEFI rootkit是以在UEFI中植入rootkit ,18年9月份ESET首次公开了境外 ...

  5. java常用实用类

    1.String类概念 java程序中默认导入java.lang包的,像java.lang.String等String类属于final类,用户不能扩展String类,String 类没有子类.Stri ...

  6. 常见的排序算法(直接插入&选择排序&二分查找排序)

    1.直接插入排序算法 源码: package com.DiYiZhang;/* 插入排序算法 * 如下进行的是插入,排序算法*/ public class InsertionSort {    pub ...

  7. cf1110d 线性dp

    很精练的一道题 /* dp[i][j][k]表示值i作为最大值结束的边剩k条,i-1剩下j条的情况的结果 dp[i][k][l]是由dp[i-1][j][k]的j决定的,因为k+l是被留下给后面用的, ...

  8. Linux基础一:Linux的安装及相关配置

    1. 计算机操作系统简介    1) 操作系统的定义:操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间.    2) 操作系统的内核的定义:操作系统的内核是一 ...

  9. git bash here 的 ~/.bashrc 配置文件。和 vue/cli 3. 0 的 .vuerc文件(preset )

    今天就来讲一下git有关的小技巧,.bashrc文件是用户配置文环境变量的文件,每次git bash会首先运行里面的内容 1.自动运行 每次进入git bash都会先读取.bashrc里面的内容,因此 ...

  10. Datagrip导入导出为一个sql文件详细说明 (mysql)

    Datagrip导入导出为一个sql文件详细说明 导出: (我的无法截图, 借用一张) 导入: (我的无法截图, 再借用一张) 完