2016-12-29 68 views
0

我有一個返回promise(使用Q)的函數,並且通知似乎並沒有在正確的時間發生。 onFulfilled和onRejected回調按預期工作,但進度回調只有在async.whilst()完成運行後纔會觸發,並立即觸發所有內容。async.whilst()中的Deferred.notify()在回調之前不會觸發進度處理程序

這是函數

function generateSentences(data, num, options) { 
    var deferred = Q.defer(); 
    const markov = new Markov(data, options); 
    markov.buildCorpus() 
     .then(() => { 
      var count = 0; 
      async.whilst(
       function() { return count < num; }, 
       function (callback) { 
        markov.generateSentence() 
         .then(result => { 
          console.log("Count: " + count); 
          deferred.notify(count/num); //update progress 
          count++; 
          callback(null); 
         }, (err) => { 
          deferred.reject(err.toString()); 
          count++; 
         }); 
       }, 
       function (err, n) { 
        //PROGRESS EVENTS DON'T HAPPEN UNTIL HERE 
        deferred.resolve(generatedSentences); //finish 
       } 
      ); 
     }, (err) => console.log(err)); 
    return deferred.promise; 
} 

,這是使用承諾

function generateScript() { 
    fs.readdir(parser.videoBasePath, function (err, files) { 
     parseFiles(files, parser.parse).then((a) => { 
      console.log("Total Lines: " + fullScript.length + "\n"); 
      fullScript = _.shuffle(fullScript); 
      markov.generateSentences(fullScript, 20).then((data) => { 
       console.log(data); 
      }, (err) => { 
       console.log(err); 
      }, (progress) => { 
       console.log(progress); 
      }); 
     }); 
    }); 
} 

我讀過一些線程像this說我需要環繞通知()一個setTimeout的,但它似乎沒有影響任何東西。

+0

診斷,如果你註冊進度回調內'generateSentences()'immedi在創建'deferred'之​​後,它的行爲與現有的進度回調相同還是不同? –

+0

也許這就是爲什麼混合承諾和異步被認爲是*壞事要做的* –

+0

@ Roamer-1888,剛剛嘗試過,它的行爲與現有的回調相同。我不知道混合promise和async是不好的練習,這是我第一次嘗試一個nodejs項目。這就是說,我試圖從其中一個解決方案,消除異步的需要,但仍然遭受同樣的問題 –

回答

0

我讀過Promises + async.js不會混合(但找不到任何可以說的東西!!),我真的不明白爲什麼這應該是一個問題在這種情況下說實話

話雖如此,還有你的代碼似乎沒有異步成爲可能,所以試試這個,看看工程的進度沒有更好

function generateSentences(data, num, options) { 
    var deferred = Q.defer(); 
    const markov = new Markov(data, options); 
    const genSentence = count => markov.generateSentence() 
     .then(result => { 
      console.log("Count: " + count); 
      deferred.notify(count/num); //update progress 
      if (count < num) { 
       return genSentence(count + 1); 
      } 
     }); 
    markov.buildCorpus() 
     .then(() => genSentence(0)) 
     .then(() => deferred.resolve(generatedSentences)) //finish 
     .catch(err => deferred.reject(err.toString())); 
    return deferred.promise; 
} 

最起碼,代碼是(在我看來)一個小清潔劑無論如何

+0

絕對清潔,謝謝。我試過你的解決方案[嘻嘻](https://gist.github.com/anonymous/bad9c379a371a9529eff8033ce22cfa9),但我似乎仍然會遇到同樣的問題。我注意到的一件事是,如果我將'return genSentence'行註釋掉只能循環運行一次,那麼進度回調就能正常工作。這使我相信notify()不喜歡我們如何實現它的遞歸性質,以及async.js如何實現它? –

+0

從未成爲Promise進展的「粉絲」 - 一些早期的實現已經實現了,我甚至修改了一個頗受好評的Promise實現,以包含「進展鏈」 - 但最終,從未真正看到它的需求 - 這似乎成爲承諾的一般方式 –

+0

雖然我的問題會有任何解決方法嗎?承諾的進展似乎是唯一符合我的使用案例。 –

相關問題