2017-01-23 48 views
1

語境不能在打字稿與發電機編譯異步代碼

  1. 在我的旅程打字稿,我被告知,阻塞調用永遠不應該異步代碼內進行。

  2. 我還使用了生成器,因爲它們使目錄遍歷變得容易並避免用完堆棧空間。

然而,當我結合異步代碼(在這種情況下:readdir)與發電機,編譯器會抱怨說產量僅能在發電機使用,導致我覺得編譯器不能夠結合關閉,生成器和異步代碼,一氣呵成。

function *yyyymmGenerator(dir: string, props: Props) { 
    const fs = require("fs"); 
    const yyyy = props.range.getUTCFullYear().toString(); 
    const mm = props.range.getUTCMonth().toString(); 
    const start = `${yyyy}-${mm}`; 

    const files = fs.readdir(dir, function(err, files) { 
     for (let i = 0; i < files.length; i++) { 
      const file: string = files[i]; 
      if (file.localeCompare(start) >= 0) { 
       const d = `${dir}/${file}`; 
       yield file; 
      } 
     } 
    }); 
} 

error TS1163: A 'yield' expression is only allowed in a generator body. 

問題

這將是在這樣的情況下推薦的最佳做法?

如果我簡單地考慮一切同步,阻止代碼但在承諾內「包裝」呼叫,那會好嗎?

+0

見http://stackoverflow.com/questions/41326217/js-how-to-use-generator-and-回報率低 –

回答

1

你可以做類似事情(調用回調內部next功能):

const gen = yyyymmGenerator(args); 

function callback(err, files) { 
    if(err) return gen.throw(err); 
    gen.next(files); 
    // Print all files returned by the generator 
    for(file of gen) { 
    console.log(file); 
    } 
} 

function *yyyymmGenerator(dir: string, props: Props) { 
    const fs = require("fs"); 
    const yyyy = props.range.getUTCFullYear().toString(); 
    const mm = props.range.getUTCMonth().toString(); 
    const start = `${yyyy}-${mm}`; 

    const files = yield fs.readdir(dir, callback); 

    for (let i = 0; i < files.length; i++) { 
     const file: string = files[i]; 
     if (file.localeCompare(start) >= 0) { 
     const d = `${dir}/${file}`; 
     yield file; 
     } 
    } 
} 

gen.next(); // Start generator 
+0

我瞭解您提出的解決方案,我認爲它原則上可行。但是,我想了解我是否應該(或者可以)認爲錯誤信息是編譯器在涉及的範圍方面受到限制的證據。或者即使它可以被認爲是編譯器中的一個錯誤。我想提出一個問題,但首先我想了解編譯器是否因錯誤或設計抱怨。有任何想法嗎? –

+0

編譯器抱怨是因爲你在'function *'(回調函數)之外使用'yield',這是合乎邏輯的,因爲當你的異步函數被調用時,生成器的執行不會停止,在你的例子中,生成器可能是在執行readdir的回調之前終止 –