2016-01-26 36 views
2

我有這段代碼是我爲一個名爲Poolio的NPM模塊編寫的小型API的一部分。對於那些支持錯誤優先回調以及承諾的人來說,我的問題似乎是一個常見問題 - 我們如何在維護API和來自API的一致返回值的同時支持這兩個問題?例如,如果我有條件地從我的API返回一個承諾,這取決於我的lib的使用者是否提供回調,在我看來這有點尷尬。在不調用'then'的情況下解析Promise

lib的使用者可以提供回調或使用Promise then功能,但不能同時使用。

這裏是我的lib中導出的功能,我想promisify:

Pool.prototype.any = function (msg, cb) { 

    var workId = this.counter++; 
    var self = this; 

    return new Promise(function (resolve, reject) { 

     if (typeof cb === 'function') { 
      self.resolutions.push({ 
       workId: workId, 
       cb: cb 
      }); 
     } 
     else { 
      self.resolutions.push({ 
       workId: workId, 
       resolve: resolve, 
       reject: reject 
      }); 
     } 

     if (this.available.length > 0) { 
      var cp = this.available.shift(); 
      cp.workId = workId; 
      cp.send(msg); 
     } 
     else { 
      self.msgQueue.push({ 
       workId: workId, 
       msg: msg 
      }); 
     } 
    }); 

}; 

我的問題是 - 如果用戶提供原有的功能參數的回調函數,我怎麼能解決的承諾沒有調用'然後'? 對不起,很難解釋,但希望你能理解。

也有這個有趣的問題: Do never resolved promises cause memory leak?

+2

解決的承諾無關用'然後'......一個承諾可以獨立於任何被調用的'then'回調來解決 –

+1

*如果*那麼在promise上調用then,然後從promise中調用resolve應該調用所有附加的then,對吧?換句話說,如果沒有thens,那麼調用resolve就不會有效果,但如果有thens,那麼這些thens應該被調用。我的問題是如何避免打電話給他們。 –

+0

是的,也有任何當時的「附加」的決議後,將被稱爲「立即」(在引號中,因爲它不是明確的剪切) –

回答

2

這其實非常簡單。只有你可能錯過了它,因爲它隱藏在那些糾結的代碼中。

基本上你這樣做:

var promise = new Promise(function (resolve, reject) { /*....*/}); 

if (typeof cb === 'function') { 
    promise.then(cb); 
} else { 
    return promise; 
} 
+0

嗯,這是一個錯誤優先回調,如果有錯誤,它會出現在正確的位置?完全無視任何「自我」的 –

+1

。分辨率「(不是我明白這是什麼) –

+0

是的,這不適用於我的情況,我也不確定它是否正確。如果您好奇,這是有問題的圖書館:https://github.com/ORESoftware/poolio –

1

其實,這是一個很常見的事做的API(mongodb-driver example)。基本上,編寫一個接受回調的私有函數,編寫一個檢查cb的公共函數並在必要時編寫它。從github上使用的代碼(_any可能需要重構,你並不需要檢查,如果CB是例如一個功能,也許其他的一些東西):

// private function 
var _any = function(msg, cb) { 
    if (this.kill) { 
    console.log('warning: pool.any called on pool of dead/dying workers'); 
    return; 
    } 

    debug('current available pool size for pool_id ' + this.pool_id + ' is: ' + this.available.length); 
    var workId = this.counter++; 

    if (typeof cb === 'function') { 
    this.resolutions.push({ 
     workId: workId, 
     cb: cb 
    }); 
    } else { 
    workId = -1; 
    } 

    if (this.available.length > 0) { 
    var cp = this.available.shift(); 
    cp.workId = workId; 
    cp.send(msg); 
    } else { 
    this.msgQueue.push({ 
     workId: workId, 
     msg: msg 
    }); 
    } 
}; 

// public exposed function 
Pool.prototype.any = function(msg, cb) { 
    if (typeof cb === 'function') { 
    // cb is provided, no action is required here 
    return _any(msg, cb); 
    } 

    // no cb, wrap the call inside a Promise and provide a cb 
    return new Promise(function(resolve, reject) { 
    _any(msg, function(err, data) { 
     if (err) reject(err); 
     else resolve(data); 
    }); 
    }); 
} 
+0

如果沒有回調,那麼您不會返回承諾,因此調用'pool.any()。then()'不起作用。 – slebetman

+0

@slebetman'返回新的Promise()'似乎正在向我返回一個承諾。 OP可以檢查'_any()'裏面是否存在'msg',我在這裏概述了不用全部錯誤檢查來編寫整個代碼的想法。 – Shanoor

+0

啊,是的,錯過了 – slebetman

相關問題