0

How would I write the following without jQuery?

var dfd = $.Deferred()
dfd.done(done)
dfd.resolve()

function done() {
   console.log('done')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Phillip Senn
  • 46,771
  • 90
  • 257
  • 373
  • Can't you use ES6 promises directly? Plus, your deferred (aka promise) is resolved directly without any async job, but I guess your reallife usecase is different? – sp00m Sep 13 '17 at 17:18
  • Yes, I can. Yes, my real life use case needs to wait until something else happens. – Phillip Senn Sep 13 '17 at 17:21
  • Deferreds are pretty much considered an anti-pattern now and there is a reason they are not directly supported in ES6. What problem are you really trying to solve? Any basic tutorial on ES6-standard promises will show you how a standard promise can be created and resolved using the Promise executor. Are you specifically asking how you make a deferred object (something that is now frowned upon) in ES6? Or what is the real problem to solve here? With as much rep as you have, you should be able to write a more complete and meaningful question. – jfriend00 Sep 13 '17 at 19:59
  • For a discussion of deferreds (instead of promises) being an anti-pattern, see here: [When would someone need to create a deferred?](https://stackoverflow.com/questions/32853105/when-would-someone-need-to-create-a-deferred/32857145#32857145). – jfriend00 Sep 13 '17 at 21:02
  • And, for an example of creating a deferred using standard promises, see [here](https://stackoverflow.com/questions/37651780/why-does-the-promise-constructor-need-an-executor/37673534#37673534). – jfriend00 Sep 13 '17 at 21:27

3 Answers3

6

Use native promises:

Promise
  .resolve()
  .then(done);

function done() {
   console.log('done')
}

Update

Without the chain:

let op = Promise.resolve();
op.then(done);

function done() {
   console.log('done')
}
alexmac
  • 19,087
  • 7
  • 58
  • 69
5

    function Deferred (){
      let res,rej,p = new Promise((a,b)=>(res = a, rej = b));
      p.resolve = res;
      p.reject = rej;
      return p;
    }

You just need to expose resolve and reject to make it work.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

The problem with using native promises is that the resolve and reject handler is provided in the callback, so if you try and call them before they are actually assigned.

In my opinion it's more robust to just implement a deferred yourself for example:

function deferred() {
  let thens = []
  let catches = []

  let status
  let resolvedValue
  let rejectedError

  return {
    resolve: value => {
      status = 'resolved'
      resolvedValue = value
      thens.forEach(t => t(value))
      thens = [] // Avoid memleaks.
    },
    reject: error => {
      status = 'rejected'
      rejectedError = error
      catches.forEach(c => c(error))
      catches = [] // Avoid memleaks.
    },
    then: cb => {
      if (status === 'resolved') {
        cb(resolvedValue)
      } else {
        thens.unshift(cb)
      }
    },
    catch: cb => {
      if (status === 'rejected') {
        cb(rejectedError)
      } else {
        catches.unshift(cb)
      }
    },
  }
}

const d = deferred()

setTimeout(() => {
  d.resolve('good')
}, 1000)

// Will be called after 1s
d.then(value => console.log('#1 resolved!', value))

setTimeout(() => {
  // Will be called after 3s and executed right away as it's already resolved
  d.then(value => console.log('#2 resolved!', value))
}, 3000)
Dominic
  • 62,658
  • 20
  • 139
  • 163