1. 实现数组扁平化:
原理
: 数组扁平化即 将一个多维数组变为一维数组 ,核心方法
: 声明一个新的空数组,然后遍历整个数组,若arr[i] 不是 一个数组就将它添加到新数组中;若它是一个数组,就将它继续遍历,再将它中的每一项添加到新数组中
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
数组中的reduce方法,该方法用于数组的归并,它与迭代方法(filter、map)一样都会对数组进行遍历,不同的是reduce方法接收两个参数第一个参数为函数类型用于写程序,第二个参数为初始迭代值,可以说设置任何数据类型;第一个参数,它的第一个参数指上一次调用函数的返回值,第二个参数是指当前元素;
这里result的初始值为 [ ], 用Array.isArray()这个方法判断循环的项是否是一个数组类型,再结合三元表达式,是数组就重新循环遍历,不是数组就用concat方法将它与result合并起来
2. 红任务与微任务的执行顺序
//同步代码
console.log('script start')
//异步函数()
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
//定时器 (红任务)
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
//promise.then() (微任务)
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
//同步代码
console.log('script end')
执行结果:
(1)知识点:
setTimeout、Promise、Async/Await 的区别
事件循环中分为宏任务队列
和微任务队列
其中setTimeout
的回调函数放到宏任务队列里,等到执行栈清空以后执行
promise.then
里的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的-同步代码-执行完再执行
async函数表示函数里面可能会有异步方法,await后面跟一个表达式
async方法执行时,遇到await会立即执行表达式
,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行
(2)js解析流程:
js运行机制是从上至下的,先执行同步任务,在执行异步任务;
- 所以毫无疑问最先执行
script start
,继续向下执行; - 遇到async1( ) ,因为async,await是由promise包装形成的,
promise一旦定义就会被立即执行
, 在执行async1异步函数中,先遇到 await async2(),就再跳到async2异步函数,输出async2 end
,并返回promise
对象;因为await
执行完后,会让出线程。async标记的函数会返回一个Promise对象; - 接着遇到setTimeout定时器它是一个
宏任务
,是放在任务队列中不会立即执行,等待微任务执行完成之后才执行; - 再接着遇到了 new promise 先输出
promise
其中的resolve()
会放到回调队列
中,等同步任务执行完毕后执行。 - console.log(‘script end’) 就输出
script end
, 就此同步任务执行完毕。 - 开始执行回调队列中任务,会先执行回调队列中的微任务,在执行宏任务;promise.then()后面的都为微任务,所以从上至下依次输出
async1 end
、promise1、promise2
;最后在执行setTimeout这个宏任务中的代码setTimeout