2013-08-27 78 views
0

我有我需要遵循嚴格的JavaScript API的命名方案,它看起來像這樣:返回對象調用函數裏面回調

var Items = function() { 
    this.items = []; 
}; 

Items.prototype.get() { 
    db.items.find(function(err, items) { 
     this.items = items; 
    }); 
    return this.items; 
} 

的問題是異步調用(db.items.find ..)在沒有時間的get之前完成()方法返回一個空this.items ..

客戶需要做出這樣的呼籲:

items = new Items(); 
console.log(items.get()); 

什麼是處理異步調用的最佳實踐他重新按照API命名方案仍然嚴格

是否有一些本地方式,我可以讓()等待回調裏面的回調還是我需要某種異步庫嗎?

+0

我不清楚命名方案與你的問題有什麼關係,這似乎更多關於異步問題。你是否試圖說你不能改變'.get()'方法的名稱或參數(所以你不能設置它來使用回調或其他)? – nnnnnn

+0

@nnnnnn,我就是這麼說的。我需要遵守這個命名方案(不會更改.get())的名稱或參數),原因有很多。 – Niklas9

+0

無論您是否嚴格要求,都無法在JavaScript中進行異步調用。雖然像C#這樣的語言支持使異步編程易於閱讀和編程,但JavaScript具有回調。 (在C#中,'Console.Writeline(await items.Get())')。 – WiredPrairie

回答

0

我設法用SilkJS(http://www.silkjs.net/),這是類似的節點,它之上構建V8來解決這一點,但它在同步運行模式。

這種方式我設法保持給定的API規範。

+0

這可能是一個愚蠢的問題,但你是否嘗試過在回調中返回? – DrakaSAN

+0

@DrakaSAN是的,這只是返回做回調調用,這是預計將無效 – Niklas9

0

編輯:

你正在尋找顯然什麼可能可以使用wait.for(https://github.com/luciotato/waitfor)。雖然我還沒有使用它,所以我不確定它會滿足您的需求。你需要的方法是wait.forMethod

以前的答案:

沒有辦法,你可以在一個同步的方式寫異步代碼。另外,混合異步和同步方法並不是一個好主意。您正試圖定義一個同步方法Item.prototype.get,但在裏面您正在使用異步方法db.items.find,這使得Item.prototype.get成爲一個異步函數。爲了得到這個工作,你必須將Item.prototype.get定義爲一個具有回調的正確的異步函數。

Items.prototype.get(fn) { 
    db.items.find(function(err, items) { 
     return fn(err, items); 
    }); 
} 

然後,您可以把它作爲

items = new Items(); 
items.get(function(err, items){ 
    console.log(items); 
} 
+0

感謝您分享此內容。我現在嘗試了waitfor,但是我無法讓它與貓鼬一起工作,請參閱我的要點 - https://gist.github.com/Niklas9/6370614。它只是輸出'之前',似乎死於第13行.. – Niklas9

+0

此外,行20(wait.launchFiber(test);)顯然是必需的,因爲這是什麼使程序運行功能測試的實際調用..我怎麼可能用我的API規範來實現?我想.get()來做這個調用,而不是wait.launchFiber() – Niklas9

+0

我還沒有真正使用過wait.for,所以我不能幫你解決問題。但是,如果wait.for不適合你,也許ES6生成器(http://blog.alexmaccaw.com/how-yield-will-transform-node)會? – asleepysamurai