2012-10-04 36 views
0

所以...我知道這不是正確的的方式......但我有一個框,我已經把自己導入,如果我能找到一種方法有一個「取」請求表現同步於Node.js的node.js中的同步行爲

是的,我已經試過節點同步(這看起來像它應該工作)

情景是這樣的

  • 讀取參數字符串從文件(完成,工作正常)
  • 遞歸記號化字符串,它分塊成鍵&值(做,做工精細)
  • 製作到谷歌的調用轉換爲每個值(休息!)翻譯
  • 重新組裝參數字符串,寫回輸出文件(做,做工精細)

我知道該怎麼做調用Google翻譯(可以很容易地做到這一點對整個字符串),但不能讓我的腦海裏圍繞着如何獲得的順序包裹一個異步回調與對數據集所需的參數化字符串進行遞歸排隊。

如果我可以調用Web服務的行爲就好像它是同步的,那麼這很簡單。例如

read string (while not EOF) 
    recurse (get the next token) 
     translate the fragment (which is done with request.get() 
     add translated fragment to the current string 
    assemble translated string 
    write to file 

節點同步實例的工作,但我無法得到它與request.get()工作。

有什麼建議嗎?

摘錄

// this function gets passed in a string and recursively pulls out and 
// attempts to translate tokens. It needs to do this as the data source 
// contains "key" = "fragment" + $(paramter1) + fragment + $(parameter2) etc 

function getTokenSegment(sourceString){ 

s = sourceString; //lazy 

// if the string contains a parameter 
if (s.indexOf(leadingDelimiter) != -1) {  

    // extract the tokens...omitted the error checking (which all works) 
    translatedToken = syncTranslate(token); // <--- THIS IS WHAT I WANT... 
    parameter = s.substring(token.length+1, s.indexOf(trailingDelimiter)+1); 
    remainder = s.substring(token.length + parameter.length+1, s.length); 

    translatedString = translatedString + translatedToken + parameter 

     // recursive call to get the rest of the string 
     + getTokenSegment(remainder); 
} 
else { 

    // the remainder of the string can be translated intact 
    translatedToken = syncTranslate(s); 
    translatedString = translatedString + translatedToken; 
} 
return (translatedString); 
} 

function syncTranslate(stringToTranslate) { 
    var sync = require('sync'); 
sync(function(){ 
    var result = translate.sync(null, {key: key, q: stringToTranslate, target: language}); 
}) 
    return result; 
} 


// translate module is from Mike Holly -- https://github.com/mikejholly/node-google-translate 
// and worked perfectly when I used it on non-parameterized strings. only edit is the NULL as the 
// first parameter in the callback, copied from the node-sync simple example] 


var request = require('request') 
    , _ = require('underscore') 
    , querystring = require('querystring') 
    , util = require('util') 

module.exports = function(opts, callback) { 

// parse & default the arguments 
opts = _.defaults(opts, { 
    source: 'en', 
    target: 'fr', 
    key: 'secret', 
    sourceText: 'text' 
}); 

var url = 'https://www.googleapis.com/language/translate/v2?' + querystring.stringify(opts); 

request.get(url, function(err, response, body){ 

    if (err) throw err; 

    // parse the returned JSON 
     var json = JSON.parse(body); 
     if (json.error) { 
      throw json.error.message; 
    } 
    var strings = util.isArray(opts.sourceText) ? opts.sourceText : [opts.sourceText]; 

    var result = {}; 
var translatedString = ''; 
    strings.forEach(function(original, i){ 
     result[original] = json.data.translations[i].translatedText; 
    translatedString = result[original]; 

    }); 

    callback(null, translatedString); 

    }); 

}; 
+2

你能告訴一個代碼示例,所以我們可以提出一個異步的方式來做到這一點?另外,我相信「請求」NPM包有一個同步獲取方法。 – Brad

+0

布拉德釘了它兩次:請提供源代碼和請求模塊將做你想要的GTranslate。 – Mamsaac

+0

謝謝你們 - 添加了一段摘錄,希望這樣做不會引入錯誤。真正關鍵的部分(對我來說)是在遞歸getTokenSegment函數中,我想對'translate'進行同步調用,以便我可以輕鬆地保留文本和令牌的順序。 – dewd

回答

0

我猜在這裏,因爲你的問題不夠清楚。我很欣賞你的困難,因爲很難談論軟件。我想你忘了換你的代碼中的同步塊:

// Run in a fiber 
Sync(function(){ 

    // your code 

}) 

來源:https://github.com/0ctave/node-sync#examples

我給你一個提示。首先嚐試最簡單的任務。嘗試翻譯只有一個詞,然後使用翻譯的詞。在Sync內做這件事。當這種方式有效時,您更信任該軟件,並且更有信心繼續更復雜的事情。

+0

謝謝 - 實際上,我沒有將代碼包裝在Sync塊中,遵循github上的基本示例。然而,我會按照你的建議方法絕對重試... – dewd

+0

所以我發現似乎是一個可行的路徑,儘管它涉及在兩個地方使用同步功能 - 一旦包裝遞歸調用,另一個包裝在進行異步調用的遞歸函數內調用。絕對不是首選的node.js風格...但它的95%完成和重新開始之間的區別...這裏有一個鏈接https://gist.github.com/3837794 – dewd

+0

...我感謝你nalply! – dewd

0

用於在node.js中寫入同步代碼的非常受歡迎的模塊是async。對於你的問題,我會嘗試waterfall功能:

async.waterfall([ 
    // your first function 
    function(callback){ 
     callback(null, 'one', 'two'); 
    }, 
    // your second function 
    function(arg1, arg2, callback){ 
     callback(null, 'three'); 
    }, 
    // your third function 
    function(arg1, callback){ 
     // arg1 now equals 'three' 
     callback(null, 'done'); 
    } 
], function (err, result) { 
    // result now equals 'done'  
}); 
+0

謝謝zeMirco。我想過使用異步,但我不確定如何將可變長度遞歸映射到回調結構。我後來發現可以幫助解決類似問題的模式上有一些帖子。 http://procbits.com/2011/10/29/a-node-js-experiment-thinking-asynchronously-recursion-calculate-file-size-directory/&http://metaduck.com/post/2675027550/asynchronous -iteration圖案-在節點-JS – dewd