有人在面试蚂蚁金服时,遇到过这么一道面试题,要求现场手写实现方式:
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const subFlow = createFlow([() => delay(1000).then(() => log("c"))]);
createFlow([
() => log("a"),
() => log("b"),
subFlow,
[() => delay(1000).then(() => log("d")), () => log("e")],
]).run(() => {
console.log("done");
});
// 需要按照 a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印
按照上面的测试用例,实现 createFlow
:
flow
是指一系列 effects
组成的逻辑片段。flow
支持嵌套。effects
的执行只需要支持串行。class Flow {
constructor(queue) {
this.queue = queue;
}run(callback) { } }
run 方法用于串行执行操作队列queue,都完成后,执行callback(如果有的话)。
异步+串行,可以想到基于 Promise 链,再加上数组,可以考虑直接用 reduce 来把数组转成 Promise 链
class Flow {
constructor(queue) {
this.queue = queue;
}
run(callback) {
let p = Promise.resolve();
p = this.queue.reduce((prev, obj) => {
if (typeof obj === "function") {
prev = prev.then(obj);
} else if (obj instanceof Flow) {
prev = prev.then(() => {
return obj.run();
});
} else if (Array.isArray(obj)) {
const temp = new Flow(obj);
prev = prev.then(() => {
return temp.run();
});
}
return prev;
}, p);
if (typeof callback === "function") {
p = p.then(() => {
return callback();
});
}
return p;
}
}
function createFlow(arr) {
return new Flow(arr);
}
function log(...args) {
console.log(new Date(), ...args);
}
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const subFlow = createFlow([() => delay(1000).then(() => log("c"))]);
createFlow([
() => log("a"),
() => log("b"),
subFlow,
[() => delay(1000).then(() => log("d")), () => log("e")]
]).run(() => {
console.log("done");
});
这道面试题主要的目的是考察对于异步串行流的控制,巧妙的利用自身的递归设计来处理传入的参数也是一个 flow
的情况,在编写题目的过程中展示你对 Promise 的熟练运用,一定会让面试官对你刮目相看的~
祝大家在大环境不好的情况下,都能拿到自己满意的 offer,加油。
“前端面试题宝典”经历接近一年的迭代打磨,目前已经提供了小程序刷题、PC端访问(https://fe.ecool.fun/)。
截至2022年4月2日,已经录入前端常见面试题832题,想刷前端面试题的小伙伴千万不要错过。
我们在近期推出了简历指导、模拟面试等增值服务,有想了解的小伙伴们可以添加小助手微信(interview-fe)进行咨询哦~