多多面试(day7)
Opened this issue · 1 comments
robbiemie commented
知识点
- ssr 渲染原理
- 补水(hydration)的过程
- ssr 返回的html片段,如何进行事件绑定
编程题
// 1. 将下面对象转换成新的结构
const entry = {
a: {
b: {
c: {
dd: "123"
}
}
},
d: {
e: "234"
},
f: "345"
}
// output: { 'a.b.c.dd': '123', 'd.e': '234', f: '345' }
题解
function travel(obj) {
function isObject(value) {
return typeof value === 'object' && value !== null;
}
if(!isObject(obj)) return obj;
const target= {};
function clone(key, value, path = '') {
const pathKey = path ? `${path}.${key}` : key;
if(isObject(value)) {
for(let k in value) {
clone(k, value[k], pathKey)
}
} else {
target[pathKey] = value;
}
}
for(let key in obj) {
clone(key, obj[key], '')
}
return target;
}
const output = travel(entry)
console.log(output);
- 实现如下函数
const res = lastSuccessPromise([
new Promise(resolve => setTimeout(() => resolve(1), 200)),
2,
Promise.reject(new Error('something wrong'))
])
res.then(v => {
console.log(v); // 1
})
function lastSuccessPromise(iterable) {
if(!Array.isArray(iterable)) return Promise.reject(new Error('iterable is not a array type'));
if(iterable.length === 0) return Promise.reject(new Error('iterable is empty'));
let successQueue:Promise<number>[] = [];
let failQueue:Promise<number>[] = [];
let iterableTotal = iterable.length;
return new Promise((resolve, reject) => {
function handleFinally() {
if(successQueue.length + failQueue.length === iterableTotal) {
if(successQueue.length === 0) return reject(new Error('success is empty'));
// 获取最后一个成功返回值
resolve(successQueue.pop());
}
}
function handlePromise(promise) {
promise.then(res => {
successQueue.push(res);
}).catch(e => {
failQueue.push(e);
}).finally(e => {
handleFinally()
})
}
for(let item of iterable) {
if(item instanceof Promise) {
handlePromise(item);
} else {
successQueue.push(item);
}
}
// 如果全是基础类型
handleFinally();
})
}
const res = lastSuccessPromise([
new Promise(resolve => setTimeout(() => resolve(1), 200)),
2,
Promise.reject(new Error('something wrong'))
])
res.then(v => {
console.log(v); // 1
})
- 实现一个 requestUrls 函数
/**
* 入参: ['url1', 'url2', 'url3'];
* 已知: url1、url2、url3 请求耗时分别是 200ms,100ms,300ms,结果返回值分别是 1,2,3
* 请求执行后,返回的结果值分别是 200ms 后输出:1,2;300ms 后输出 3
*/
function requestUrls(urls) {
if(urls.length === 0) return;
let requestQueue:any[] = [];
let curTaskIndex = 0;
function checkTaskCompleted(index) {
const tasks = requestQueue.slice(curTaskIndex, index);
const i = tasks.indexOf(item => item instanceof Promise);
if(i > -1) return;
for(let res of tasks) {
console.log(res);
}
curTaskIndex = index
}
function execTask() {
for(let index in urls) {
const promise = fetch(urls[index]);
promise.then(res => {
requestQueue.splice(+index, 1, res);
checkTaskCompleted(index);
})
requestQueue.push(promise);
}
}
execTask()
}
const urls = ['url1', 'url2', 'url3']
requestUrls(urls);
MockLo commented
黑皮帅哥笔试题:
有这样的一个函数:
function asyncFn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.2) {
console.log('inner success');
resolve('success');
} else {
console.log('inner failed');
reject('failed');
}
}, 1000 * Math.random());
});
}
请实现这个函数:执行函数fn,直至成功。除非超过重试次数或者超时。
function runWithRetry(fn, retryTimes, timeout) {
// coding here
}