Q.js progress handler doesn't seem to be firin

2019-08-13 11:29发布

问题:

I'm currently using Q.js for promises, since they implement progress handlers. However, it doesn't seem like they're firing. What am I doing wrong? It seems pretty basic, so I must be missing something. (The example below is written in coffeescript)

Q = require('q')
squares = (list) ->
  deferred = Q.defer()
  result = list.map (e) ->
    r = e * e
    deferred.notify(r)
    return r
  deferred.resolve(result)
  return deferred.promise

squares([1,2,3,4,5,6,7,8,9,10])
  .then((result) ->
    console.log result
  ).progress((e) ->
    console.log e
  )

回答1:

squares is executed synchronously, thus deferred.notify and deferred.resolve are invoked before any listeners are bound. Seems like already fulfilled promises still invokes the fulfilled callbacks but not any progress callbacks. You could wrap part of the code with setTimeout like this:

Q = require('q')

squares = (list) ->
  deferred = Q.defer()
  setTimeout (->
    result = list.map (e) ->
      r = e * e
      deferred.notify(r)
      return r
    deferred.resolve(result)
    ), 0
  return deferred.promise

squares([1,2,3,4,5,6,7,8,9,10])
  .progress((e) ->
    console.log e
  ).then((result) ->
    console.log result
  )


回答2:

This discussion thread on github : https://github.com/kriskowal/q/issues/188 between the OP and the package maintainer provides a detailed explanation and solution.

In summary, listeners must be registered via a call to .progress before the promiser makes calls to .notify. This means examples where the promiser is calling notify synchronously will likely occur before the .progress listener is registered, and thus the example will appear broken. The addTimeout solution provided by @bennedich satisfies this requirement.

This ordering requirement is not consistent with the experience of a listener registered via a call to .then after the promiser calls .resolve. In this scenario the listener is still called despite the ordering. But for that listener to be called after, the Q package has to perform magic (see the guy in the wizard hat : https://github.com/kriskowal). The same magic is deliberately NOT provided for listeners to .progress thus the ordering requirement mentioned in this and previous answers.

HTH