2013-08-22 82 views
1

我使用某個Node.js類進行文本分類。在最簡單的形式,它看起來像這樣:將異步函數轉換爲同步函數

function TextCategorizer(preprocessors) { 
     ... 
} 

「預處理程序」是形式的函數數組:

function(text) { 
    return "<modified text>" 
} 

他們可以使用,例如,以去除標點符號,轉換成下殼體等

我可以使用TextCategorizer這樣的:

var cat = newTextCategorizer(preprocessors); 
cat.train(text1,class1); 
cat.train(text2,class2); 
... 
console.log(cat.classify(text3,class3); 

的preproces爲了每個訓練文本和分類文本,都會調用sors。

現在,我需要添加一個新的預處理器函數 - 拼寫糾正器。最好的拼寫糾正我發現作品異步(通過Web服務),因此,功能如下:

correctSpelling(text, callback) { 
    ... 
    callback(corrected_version_of_text); 
} 

即它不返回值,而是要求與價值的回調函數。

我的問題是:我如何使用correctSpelling函數作爲預發送器陣列中的一個預處理器發送給TextCategorizer?

+0

爲什麼不異步使用它呢?異步是節點口頭禪。 –

+0

作爲一個獨立的函數,我當然可以異步使用它。但正如我在問題中所解釋的那樣,我想用它作爲另一個模塊的輸入,它需要一個同步功能。 –

+0

使用異步調用將預處理程序放入關閉中。然後在這個閉包中定義你的回調,所以回調函數可以訪問預處理器數組。 – ChrisCM

回答

2

如果你想按照一定的順序放置一堆任務,你可以使用框架(npm install async)。同步稱爲「系列」的異步功能有一個特定功能。

聽起來好像您在使用同步和異步功能時遇到了問題。在這種情況下,我認爲你應該換了所有的同步功能,在異步函數像這樣

function asyncFunc(args, callback){ 
    process.nextTick(function() { 
     callback(syncFunc(args)); 
    }); 
} 

那麼你應該使用async模塊把它們結合在一起。

它看起來像這可能使異步函數的同步。

waitfor on github

+0

「系列」採用一組異步函數,按順序調用它們,並將結果返回給另一個回調函數。但是,我仍然沒有看到如何使用它來向需要同步函數的類發送異步函數... –

+0

@ErelSegalHalevi能否包含更多代碼?我不明白爲什麼你可以異步傳遞同步回調到你的函數。 –

+0

你對TextCategorizer有什麼訪問權限?如果您可以訪問源代碼,我相信您可以使用基於事件的解決方案(我將根據您的回答進行描述)。 –

1

如果以上關於我對你的問題的理解我的意見是正確的,我不相信有一種方式未asynchronizing一個異步調用你想要的方式,無需修改TextCategorizer源,你表示不會是最佳的。

我唯一的想法是在調用train()和classify()之前通過現有的預處理器列表來運行你的文檔,這將允許你遵循JoshC的建議。

1

如果你真的想要這樣做,你可以試試Fibers

var Future = require('fibers/future'), wait = Future.wait; 
var fs = require('fs'); 

// This wraps existing functions assuming the last argument of the passed 
// function is a callback. The new functions created immediately return a 
// future and the future will resolve when the callback is called (which 
// happens behind the scenes). 
var readdir = Future.wrap(fs.readdir); 
var stat = Future.wrap(fs.stat); 

Fiber(function() { 
    // Get a list of files in the directory 
    var fileNames = readdir('.').wait(); 
    console.log('Found '+ fileNames.length+ ' files'); 

    // Stat each file 
    var stats = []; 
    for (var ii = 0; ii < fileNames.length; ++ii) { 
     stats.push(stat(fileNames[ii])); 
    } 
    wait(stats); 

    // Print file size 
    for (var ii = 0; ii < fileNames.length; ++ii) { 
     console.log(fileNames[ii]+ ': '+ stats[ii].get().size); 
    } 
}).run(); 

期貨https://github.com/laverdet/node-fibers#futures