2014-05-06 65 views
3

我正在創建一個節點模塊,我希望能夠支持節點回調和Promise API。我聽到最好的東西(主要是它是最快的)的圖書館是bluebird。所以,閱讀一些文檔和查看正在使用的藍鳥一些其他庫後,我認爲這將是獲得一種方法來支持節點的回調,並承諾API的最徹底的方法:使用此代碼創建支持節點回調和承諾與藍鳥的節點庫

this.isAllowed = function(role, resource, permission, callback) { 
    var isAllowedAsync = bluebird.promisify(isAllowed); 
    return isAllowedAsync(role, resource, permission).nodeify(callback); 
}; 

然而,回調從不執行。經過一些更多的研究,我嘗試了這個:

this.isAllowed = function(role, resource, permission, callback) { 
    return new bluebird(function (resolve, reject) { 
    resolve(isAllowed(role, resource, permission)); 
    }).nodeify(callback); 
}; 

通過該代碼,節點回調和Promise API都可以工作。

以供參考,這是isAllowed方法:

var isAllowed = function(role, resource, permission) { 
    if(!lists[role] || !lists[role][resource]) { 
    return false; 
    } 

    return lists[role][resource].indexOf(permission) !== -1; 
}; 

我做得不對的第一個代碼示例或第二個例子中得到什麼我尋找的真正的方法是什麼?

+1

'isAllowed'是一個同步函數,這樣做沒有意義 – Esailija

回答

13

你的具體問題沒有意義(請參閱我的評論),所以我只是通用的。有兩種方式公開雙重承諾/回調API。

第一種方法是讓相同的函數同時支持promise和回調,如果沒有傳遞迴調參數則返回promise,或者如果回調參數未被傳遞則使用回調。

但是,這是很難實現,並且可能有一些討厭的問題,當一些參數是可選的。

要實現它,您可以做與使用100%承諾功能完全相同的功能,除了您在返回鏈的末尾添加.nodeify

// Note however this doesn't work if some arguments before 
// `callback` are optional 
function dualApi(..., callback) { 
    // acting as if you would never support callbacks at all 
    return getPromise() 
      .then(...) 
      .then(...) 
      .then(...) 
      // .nodeify at the end of the chain, NOWHERE else 
      .nodeify(callback) 

} 

第二種方法是定義一個普通的回調API,然後只需撥打promisifyAll。這很容易實現,實際上幾乎沒有理由這樣做,因爲如果用戶使用藍鳥,用戶可以很容易地自行提供模塊。