syntax for Jquery.deferred , making synchronous function return promise

…衆ロ難τιáo~ 提交于 2019-12-31 03:23:27

问题


A quick question on how to use Jquery.deferred to make a slow synchronous function return a promise instead. What I've done so far is this :

function sayIt(ms) {
    setTimeout( function() { console.log('what I say'); }, ms);
} 

function doIt() {
    return $.Deferred( function() { sayIt(2000); }).promise();
}


doIt().then( function() { console.log('ah'); });

the sayIt(2000) always goes through but the chained function after the 'then' never fires.

If I do this :

doIt().then( console.log('ah'));

the 'ah' comes up right away, and then the 'what I say' 2000ms later - what I want is of course the opposite - that after two seconds I get 'what I say' and then 'ah' right after.

Any suggestions appreciated!


回答1:


To do something synchronously, but still use a promise, do:

function slowPromise() {

    var def = $.Deferred();

    // do something slow and synchronous
    ...

    // resolve the deferred with the result of the slow process
    def.resolve(res);

    // and return the deferred
    return def.promise();
}

The effect is that you still get a promise, but that promise is already resolved, so any .then() which is subsequently registered on it proceeds immediately.

The advantage of this pattern is that if you subsequently replace the synchronous code with something asynchronous the function still has the same external interface.




回答2:


If you want to execute a function after the timeout has expired, you need to call resolve() on the Deferred object from within the timeout expiration function:

function sayIt(ms) {
  var d = $.Deferred();
  setTimeout(function() {
      console.log('what I say');
      d.resolve()
    }, ms);
  return d;
}

In this way you constrain the resolution of the Deferred object to the expiration of the timeout.

To achieve what I believe is your intent:

function doIt() {
  return sayIt(2000).promise()
}

The .promise() call is optional. It only restricts the available interface for callers: by returning a Promise instead of the original Deferred object, the caller can only react to events, but not triggering them. Reference: http://api.jquery.com/deferred.promise/.

Eventually, your original call:

doIt().then( function() { console.log('ah'); });

Will output:

// 2 seconds delay
what I say
ah 


来源:https://stackoverflow.com/questions/10664466/syntax-for-jquery-deferred-making-synchronous-function-return-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!