1. 数组转树方法
// 代码实现
function arrayToTree(array) {
let root = array[0]
array.shift()
let tree = {
id: root.id,
val: root.val,
children: array.length > 0 ? toTree(root.id, array) : []
}
return tree;
}
function toTree(parenId, array) {
let children = []
let len = array.length
for (let i = 0; i < len; i++) {
let node = array[i]
if (node.parentId === parenId) {
children.push({
id: node.id,
val: node.val,
children: toTree(node.id, array)
})
}
}
return children
}
console.log(arrayToTree(input))
2. 手写发布订阅
// 发布订阅中心, on-订阅, off取消订阅, emit发布, 内部需要一个单独事件中心caches进行存储;
interface CacheProps {
[key: string]: Array<((data?: unknown) => void)>;
}
class Observer {
private caches: CacheProps = {}; // 事件中心
on (eventName: string, fn: (data?: unknown) => void){ // eventName事件名-独一无二, fn订阅后执行的自定义行为
this.caches[eventName] = this.caches[eventName] || [];
this.caches[eventName].push(fn);
}
emit (eventName: string, data?: unknown) { // 发布 => 将订阅的事件进行统一执行
if (this.caches[eventName]) {
this.caches[eventName].forEach((fn: (data?: unknown) => void) => fn(data));
}
}
off (eventName: string, fn?: (data?: unknown) => void) { // 取消订阅 => 若fn不传, 直接取消该事件所有订阅信息
if (this.caches[eventName]) {
const newCaches = fn ? this.caches[eventName].filter(e => e !== fn) : [];
this.caches[eventName] = newCaches;
}
}
}
3. 宏任务和微任务(笔试题)
- 异步
async function async1() {
console.log('async1 start') // 同步任务
await async2() // await要等右边全部执行完毕才会进行下一步
console.log('async1 end') // 微任务
}
async function async2() {
console.log('async2') // 同步任务
}
console.log('script start') // 同步任务
setTimeout(function () {
console.log('settimeout') // 宏任务
})
async1()
new Promise(function (resolve) {
console.log('promise1') // 同步任务
resolve()
}).then(function () {
console.log('promise2') // 微任务
})
console.log('script end') // 同步任务
执行循序:
script start
async1 start
async2
promise1
script end
async1 end
promise2
settimeout
- 案例2
setTimeout(() => {
console.log(1);
}, 0);
new Promise((resolve, reject) => {
console.log(2);
resolve("p1");
new Promise((resolve, reject) => {
console.log(3);
setTimeout(() => {
resolve("setTimeout2");
console.log(4);
}, 0);
resolve("p2");
}).then(data => {
console.log(data);
})
setTimeout(() => {
resolve("setTimeout1");
console.log(5);
}, 0);
}).then(data => {
console.log(data);
});
console.log(6);
执行顺序:
2 3 6 p2 p1 1 4 5
- 案例3
console.log(11);
setTimeout(() => {
console.log(12);
let p = new Promise((resolve, reject) => {
resolve(13);
});
p.then(data => {
console.log(data);
});
console.log(15);
}, 0);
console.log(14);
输出顺序:
11 14 12 15 13