Home > OS >  How can I chain functions asynchronously using JavaScript?
How can I chain functions asynchronously using JavaScript?

Time:01-01

I was asked to create such an object called foo that can chain the function log and wait.

For example:

foo.log('breakfast').wait(3000).log('lunch').wait(3000).log('dinner');

In this scenario it prints breakfast first, waits 3 seconds, prints lunch, and then after 3 seconds it prints dinner.

I tried something like this, but it doesn't work. What did I miss?

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');

CodePudding user response:

It's always better to use promises. An implementation of this functionality could be;

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");

CodePudding user response:

For the record @Redu's excellent answer without the class sugar.

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");

CodePudding user response:

Place the call to wait inside the previous one, and as the last item, like a recursive function.

meals=['breakfast','elevenses','lunch','afternoon tea','dinner','supper'];
c=0;
wait=t=>{setTimeout(function() {
      if (c<meals.length) document.write(meals[c  ],'<br>');wait(500);
    }, t);}

wait(500);

  • Related