我一直在玩承诺并试图建立某种进度通知。
代码以正确的顺序执行所有函数,但进度更新在解析之前执行,而不是在实际发生时执行。
有谁可以指出我做错了什么?
function start(x) {
console.log("Start: " + x);
var promise = process(x);
console.log("promise returned");
promise.then(function(data) {
console.log("Completed: " + data);
}, function(data) {
console.log("Cancelled: " + data);
}, function(data) {
console.log("In Progress: " + data);
});
}
function process(x) {
var deferred = $.Deferred();
var promise = deferred.promise();
// process asynchronously
setTimeout(function() {
for (var i=0 ; i<x ; i++) {
sleep(1000);
deferred.notify(i);
}
if (x % 2 === 0) {
deferred.reject(x);
} else {
deferred.resolve(x);
}
}, 0);
return promise;
}
function sleep(sleepDuration) {
var now = new Date().getTime();
while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }
}
start(3);
答案 0 :(得分:1)
使用while()
实现的延迟计时器,将&#34;阻止&#34; - 即占用处理器。
阻止不仅会阻止其他javascript运行,还会阻止包括控制台在内的浏览器屏幕的可靠刷新。因此,当deferred.notify(i)
和console.log("In Progress: " + data)
语句被触发时,控制台不会刷新,直到处理器可以自由执行。
不出所料,解决方案在于不使用while()
。
幸运的是,javascript包含两个内置方法window.setTimeout()
和window.setInterval()
,它们在概念上与while()
闲人不同,但履行相同的角色.... 没有阻止。
window.setInterval(fn, t)
每隔t毫秒触发一次函数fn
,window.setTimeout(fn, t)
在t毫秒后触发一次函数fn
。两种方法都返回一个不透明的引用,允许它们被取消。
在下面的代码中,start()
未经修改,process()
经过大量修改,sleep()
已消失。
process()
现在执行以下操作:
setInterval()
,其功能如下:
deferred.notify()
,直到计数器i
达到指定的最大值x
,deferred.resolve()
或deferred.reject()
被叫来解决延期(及其承诺),function start(x) {
console.log("Start: " + x);
process(x).then(function(data) {
console.log("Completed: " + data);
}, function(data) {
console.log("Cancelled: " + data);
}, function(data) {
console.log("In Progress: " + data);
});
}
function process(x) {
return $.Deferred(function(dfd) {
var i = 1;
var intervalRef = setInterval(function() {
if(i < x) {
dfd.notify(i++);
} else {
clearInterval(intervalRef);
dfd[(x % 2 === 0)?'reject':'resolve'](x);
}
}, 1000);
}).promise();
}
console.clear();
start(3);
<强> Updated fiddle 强>