一道字节面试题解

2020-06-01 21:35:24 +08:00
 xiaoming1992

刚刚面了字节跳动, 题目都很(~~~~~~)基础, 但就是答得不好...视频一挂, 诶, 有好想法了 T.T

不行, 我非得把答案贴这儿, 可惜面试官不在我面前, 不然我非得告诉他, 你看, 这解答至少还凑合啊

// 题目是实现下列链式调用
const chain = new Chain()

chain
  .eat()
  .sleep(1000)
  .eat()
  .sleep(1000)
  .work()
// 我原来用的 promise 把所有方法都包裹起来, 简直丑破天际...
// 下面是新的解答
// 至于里面有些属性是不是要用 private 或者 protected 什么的, 我就懒得细究了

interface EatAction {
  name: "eat";
  params: [];
}

interface SleepAction {
  name: "sleep";
  params: [number];
}

interface WorkAction {
  name: "work";
  params: [];
}

type Action = EatAction | SleepAction | WorkAction

class Chain {
  running = false

  actions: Action[] = []

  trigger() {
    if (this.running) { return }
    const action = this.actions.shift()
    if (!action) { return }

    this.running = true

    switch (action.name) {
    case "eat":
      console.log("eat")
      this.running = false
      this.trigger()
      break
    case "work":
      console.log("work")
      this.running = false
      this.trigger()
      break
    case "sleep":
      setTimeout(() => {
        console.log("sleep")
        this.running = false
        this.trigger()
      }, action.params[0])
      break
    default:
      break
    }
  }

  eat() {
    this.actions.push({
      name: "eat",
      params: [],
    })
    this.trigger()
    return this
  }

  sleep(n: number) {
    this.actions.push({
      name: "sleep",
      params: [n],
    })
    this.trigger()
    return this
  }

  work() {
    this.actions.push({
      name: "work",
      params: [],
    })
    this.trigger()
    return this
  }
}
1819 次点击
所在节点    JavaScript
5 条回复
jason94
2020-06-01 22:15:25 +08:00
这样是不是简单一点

```ts
class Chain {
private actions: Function[] = [];
constructor() {
setTimeout(async () => {
for (const action of this.actions) {
await action.call(this);
}
});
}

eat() {
this.actions.push(() => console.log('eat'));

return this;
}

sleep(timeout: number) {
this.actions.push(() => {
console.log('sleep ', timeout);
return new Promise((resolve) =>
setTimeout(() => {
resolve();
}, timeout)
);
});
return this;
}
work() {
this.actions.push(() => console.log('work'));

return this;
}
}

const chain = new Chain();

chain.eat().sleep(1000).eat().sleep(1000).work();

```
xiaoming1992
2020-06-01 22:33:16 +08:00
@jason94 你这么写倒也挺好, 就是如果有在 constructor 之后才添加进去的事件, 就不会执行了, 如:
setTimeout(() => { chain.eat() }, 5000)
mxT52CRuqR6o5
2020-06-01 23:04:09 +08:00
```ts
class Chain{
constructor(promise){
if(promise){
this._promise=promise;
}else{
this._promise=Promise.resolve();
}
}
eat(){
return this._next(()=>{console.log('eat')});
}
work(){
return this._next(()=>{console.log('work')});
}
sleep(ms){
return this._next(async ()=>{
await new Promise(resolve=>setTimeout(resolve,ms))
});
}
_next(someAction){
const nextPromise=(async ()=>{
await this._promise;
await someAction();
})()
return new Chain(nextPromise);
}
}
```
我的思路,没测试,可能有 bug
treemonster
2020-06-01 23:06:56 +08:00
class Chain{
task=Promise.resolve()
eat() {
this.task=this.task.then(_=>console.log('eat'))
return this
}
work() {
this.task=this.task.then(_=>console.log('work'))
return this
}
sleep(t) {
this.task=this.task.then(_=>new Promise(r=>{
console.log('sleep', t)
setTimeout(r, t)
}))
return this
}
}

promise 写很简单
xiaoming1992
2020-06-02 00:00:33 +08:00
@mxT52CRuqR6o5 @treemonster 大概一瞄,应该是没什么问题的。我当时的思路就跟 4 楼的一样,可是写的丑多了。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/677624

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX