Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return a value from setTimeout() [duplicate]

I want to return the status and store its value in variable s. I will appreciate some help please.

here is my code:

let s = setTimeout( ()=>{
   this.matchService.getMatches().subscribe(ms => {
       this.matches = ms;
       let match = this.matches.find(match => match.id == id);
       let status = match.status;
       if(status == 'closed' || status == 'live') {
          this.status.name = status;
        }
        return status;
      });
  },9000);
}
like image 669
yosra Avatar asked Apr 18 '19 13:04

yosra


2 Answers

This answer here is specifically for the setTimeout question. If you work with an observable, consider the answer of bambam!

Ok, this answer might be a little weird if you don't know the concept of async. Basically the easiest is to wrap your setTimeout into a Promise, like so:

const someTimeoutAction = () => {
  // Let's return a new Promise, promising to eventually return a value
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello world');
    }, 1000);
  });
};

// The following function is an async function, that will
// help to work better with Promises.
const mainFunction = async () => {
  console.log('Waiting for status');
  const status = await someTimeoutAction();
  console.log(status);
};
mainFunction();

So what happens here?

  1. The mainFunction is called and calls someTimeoutAction.
  2. The someTimeoutAction returns a promise. The old syntax looks a bit different. This medium article document should be a good starting point.
  3. mainFunction waits for the Promise to resolve. After a second it is resolved and the value is written to status.
  4. Everything else just continues now like usual.

The code above only works for modern browsers. It does not work without a transpiler for e.g. IE11. However, the old syntax works just fine:

function someTimeoutAction() {
  // Let's return a new Promise, promising to eventually return a value
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello world');
    }, 1000);
  });
};

// The following function is an async function, that will
// help to work better with Promises.
function mainFunction() {
  console.log('Waiting for status');
  someTimeoutAction()
    .then(function(status) {
      console.log(status);
    });
};
mainFunction();
like image 105
lumio Avatar answered Oct 06 '22 01:10

lumio


Since you already have an observable, simply delay it instead of using setTimeout! Also the promise approach from the other answer is nonsense for this scenario.

this.matchService.getMatches()
    .pipe(delay(9000))
    .subscribe(ms => {
       this.matches = ms;
       let match = this.matches.find(match => match.id == id);
       let status = match.status;
       if(status == 'closed' || status == 'live') {
          this.status.name = status;
       }
  });

The bigger problem with your code is that you would never never return from subscribe. Actually you would rather delay the (I'm guessing) http call in matchService, but you didn't show the relevant code.

Note that a subscription may get triggered multiple times, again depending on what getMatches() is. You're on the wrong path here and should update your question so we can tailor you a real solution.

like image 34
baao Avatar answered Oct 06 '22 01:10

baao