re: setTimeout is a callback-style function. What would happen if we change that? VIEW POST

FULL DISCUSSION
 

Ok, that's so cool but... what about clearTimeout?

Because I'm sure many have thought about transforming setTimeout into a promise (e.g. was common in AngularJS), but there's always a catch.
There has been a debate about cancelable promises a couple of years ago, we got nothing it out of it 😕

 

This is a fantastic question. Without cancellable promises, you would not be able to cancel the setTimeout.

For a majority of use cases cancelling a promise is not needed. Though that doesn't mean it is not a valid use case. Throttling and debouncing is an example of a valid use case when you would want to cancel a promise.

The sleep implementation I created currently does not support cancellation. I have created an issue for this here: github.com/joelnet/MojiScript/issu.... This is a feature that would be great to have.

Here's a very naive implementation that could support cancellation:

const sleep = milliseconds => value => {
  let timeoutId
  const cancel = () => clearTimeout(timeoutId)
  const promise = new Promise(resolve => {
    timeoutId = setTimeout(() => resolve(value), milliseconds)
  })
  return Object.assign(promise, { cancel })
}

(async () => {
  // create promise and cancel
  const promise = sleep (1000) ('Uh oh!')
  const { cancel } = promise

  // promise to log when resolved
  promise.then(console.log)

  // cancel promise
  cancel()

  console.log('Done.')
})()

Bluebird also supports promise cancellation: bluebirdjs.com/docs/api/cancellati...

Converting this Promise to use bluebird's Promise would also work.

 

Yes, that could work! 🙌

You can also consider the approach that's been taken for cancelling a fetch promise: it's based on a "signal" that's being created by an AbortController object:

const ctrl = new AbortController()
const signal = ctrl.signal
fetch(someUrl, { signal })
  .catch(error => {
    console.log(error.name)
  })

// Later on...
ctrl.abort()
// Then it logs 'AbortError'

You can extend your sleep function to accept a signal option and listen to an abort event. Although it does seem a little overkill for something like this...

This is interesting. I'll have to create some test project with the .cancel and an AbortController. Maybe I'll create a debounce to compare the differences.

Definitely something to think about.

code of conduct - report abuse