如何使用 JavaScript 异步链接函数?

hir*_*shi 25 javascript asynchronous

我被要求创建一个名为 的对象foo,它可以链接函数logwait

例如:

foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner');
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它首先打印breakfast,等待 3 秒,打印lunch,然后在 3 秒后打印dinner

我尝试过类似的方法,但它不起作用。我错过了什么?

var foo = {
  log: function(text){
    console.log(text);
    return foo;
  },

  wait: function(time) {
    setTimeout(function() {
      return foo;
    }, time);
  }
}

foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner');
Run Code Online (Sandbox Code Playgroud)

Red*_*edu 36

使用 Promise 总是更好。此功能的实现可以是:

class Foo {
  constructor(){
    this.promise = Promise.resolve();
  }
  log(txt){
    this.promise = this.promise.then(_ => console.log(txt))
    return this;
  }
  wait(ms){
    this.promise = this.promise.then(_ => new Promise(v => setTimeout(v,ms)));
    return this;
  }
}
  
  var foo = new Foo();
  foo.log("happy").wait(1000).log("new").wait(1000).log("year");
Run Code Online (Sandbox Code Playgroud)

  • 哇哦,这是什么魔术?非常感谢,我必须检查一下 Promise 并接受它一会儿!向先生致敬并祝您新年快乐! (10认同)
  • 您可能希望使该对象可供thenable,以便可以“await foo”。还可以考虑使其不可变,以便您可以重用对象,而不会在两个执行链之间发生冲突。 (2认同)

Koo*_*Inc 13

根据记录,Redu 的出色答案没有类糖

也可以看看

const foo = {
  promise: Promise.resolve(),
  log(txt) {
    this.promise.then(_ => console.log(txt));
    return this;
  },
  wait(ms) {
    this.promise = this.promise.then(_ => new Promise(v => setTimeout(v, ms)));
    return this;
  }
};

// OR
const Foo = (defaultMs = 1000) => {
  let promised = Promise.resolve();
  return {
    log(txt) {
      promised.then(_ => console.log(txt));
      return this;
    },
    wait: function(ms) {
      promised = promised.then( _=> 
        new Promise( rs => setTimeout(rs, ms || defaultMs) ) );
      return this;
    }
  };
};

foo.log("Happy").wait(1000).log("new").wait(1000).log("year");
Foo().wait(3000)
  .log(`** From Foo ;)`).log(`Happy`).wait().log("new").wait().log("year");
Run Code Online (Sandbox Code Playgroud)