2013-10-21 122 views
1

我想定義一個承諾的函數,並返回相同的承諾,但返回的承諾解決任意超時;我的代碼如下所示:但我不確定自己是否像拒絕一樣捕捉到了一切。如何添加指定的延遲到承諾的分辨率

//Returns a promise identical to promise, except with an additional delay 
// specified by timeout. 
delayedPromise(promise, timeout) { 
    var newPromise = $.Deferred(); 
    promise.then(function(result) { 
     window.setTimeout(function() { 
      newPromise.resolve(result); 
     }, 3000); 
    } 
    return newPromise; 
} 

有沒有更好的方法來做到這一點?我是否還需要添加類似的功能來處理錯誤?

回答

2

我認爲你走在正確的軌道上,但是你錯過了一些細節 - 特別是你的delayedPromise不會使用與原始承諾相同的上下文和參數調用任何後續回調。

試試這個,而是:

function delayedPromise(promise, timeout) { 
    var d = $.Deferred(); 

    promise.then(function() { 
     var ctx = this; 
     var args = [].slice.call(arguments, 0); 
     setTimeout(function() { 
      d.resolveWith(ctx, args); 
     }, timeout); 
    }, function() { 
     var ctx = this; 
     var args = [].slice.call(arguments, 0); 
     setTimeout(function() { 
      d.rejectWith(ctx, args); 
     }, timeout); 
    }); 

    return d.promise(); 
} 

其中d.resolveWith()d.rejectWith調用是需要保存上述上下文和參數。

請注意,您的progress通知不會延遲使用此方法,但在這種情況下這些通知不一定有任何意義。

同樣,如果您確實想要拒絕承諾立即解決(不延遲),然後刪除第二個function傳遞給.then

0

我希望你能在Q insightful中找到delay的實現。 https://github.com/kriskowal/q/blob/master/q.js#L1629-L1637

Q.delay = function (object, timeout) { 
    if (timeout === void 0) { 
     timeout = object; 
     object = void 0; 
    } 
    return Q(object).delay(timeout); 
}; 

Promise.prototype.delay = function (timeout) { 
    return this.then(function (value) { 
     var deferred = defer(); 
     setTimeout(function() { 
      deferred.resolve(value); 
     }, timeout); 
     return deferred.promise; 
    }); 
}; 
+0

這實現了相同的問題的任擇議定書的原代碼 - 它不保留'this'或解決延遲迴調時整套傳遞的參數。 – Alnitak