【发布时间】:2017-05-13 09:54:43
【问题描述】:
我有一个返回承诺的函数(使用 Q),并且通知似乎没有在正确的时间发生。 onFulfilled 和 onRejected 回调按预期工作,但进度回调直到 async.whilst() 完成运行后才会触发,并立即触发所有内容。
这是函数
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 的帖子说我需要在 notify() 周围包裹一个 setTimeout,但它似乎没有任何影响。
【问题讨论】:
-
对于诊断,如果您在创建
deferred后立即在generateSentences()中注册一个进度回调,它的行为与您现有的进度回调相同还是不同? -
也许这就是为什么混合 Promises 和 async 被认为是Bad Thing To Do
-
@Roamer-1888,刚刚尝试过,它的行为与现有回调相同。我不知道混合承诺和异步是不好的做法,这是我第一次尝试 nodejs 项目。话虽如此,我尝试了另一种解决方案,消除了对异步的需求,但仍然遇到同样的问题
-
这很奇怪,我无法解释这种行为,也无法理解为什么@JaromandaX 的答案不起作用 - 他的代码看起来不错。也许microtask vs macrotask 级别存在问题。我最好的建议是放弃
async.js和Q/.notify(),转而采用更简单的方法将“通知”回调传递给generateSentences()。
标签: node.js promise q async.js