刚刚面了字节跳动, 题目都很(~~~~~~)基础, 但就是答得不好...视频一挂, 诶, 有好想法了 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
  }
}
|  |      1jason94      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(); ``` | 
|  |      2xiaoming1992 OP @jason94 你这么写倒也挺好, 就是如果有在 constructor 之后才添加进去的事件, 就不会执行了, 如:     setTimeout(() => { chain.eat() }, 5000) | 
|      3mxT52CRuqR6o5      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 | 
|  |      4treemonster      2020-06-01 23:06:56 +08:00  2 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 写很简单 | 
|  |      5xiaoming1992 OP @mxT52CRuqR6o5 @treemonster 大概一瞄,应该是没什么问题的。我当时的思路就跟 4 楼的一样,可是写的丑多了。。。 |