2016-12-29 69 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

虽然我的问题会有任何解决方法吗?承诺的进展似乎是唯一符合我的使用案例。 –

相关问题