我正在通过调用then
创建一个promise
我可以从内部报告进度吗?还是必须使用Q.defer
(具有notify
)?
var promise = doSomething().then(function () {
// somehow report progress from here
});
promise.progress(function (p) {
console.log('progress', p);
});
使用deferred.notify()
这个问题已经有一段时间没有提出了,Q
库现在支持它
var progress = 96;
deferred.notify(progress);
例如:
function doSomething() {
var deferred = Q.defer();
setTimeout(function() {
deferred.notify(10);
},500);
setTimeout(function() {
deferred.notify(40);
},1500);
setTimeout(function() {
deferred.notify(60);
},2500);
setTimeout(function() {
deferred.notify(100);
deferred.resolve();
},3500);
return deferred.promise;
}
doSomething()
.then(
function () {
// Success
console.log('done');
},
function (err) {
// There was an error,
},
function (progress) {
// We get notified of the progress as it is executed
console.log(progress);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.4.1/q.js"></script>
进度通知
承诺可以报告其进度,例如任务像上传文件一样需要很长时间。并不是所有的承诺都会实现进度通知,但对于那些实现进度通知的人,您可以使用第三个参数消耗进度值,然后:
return uploadFile() .then(function () { // Success uploading the file }, function (err) { // There was an error, and we get the reason for error }, function (progress) { // We get notified of the upload's progress as it is executed });
与fail一样,Q也提供了进度回调的简写,称为进度:
return uploadFile().progress(function (progress) { // We get notified of the upload's progress });
- 摘自官方自述
我不太清楚你所说的"通过调用then
创建承诺"是什么意思。我猜你的意思是你用一个当时定义的承诺来回报?I.e,
var iAmAPromise = someOtherPromise.then(doSomething);
如果是这种情况,那么您可以将doSomething
封装在具有适当通知的回调函数中。一个工作示例:
var Q = require('q');
function resolver(deferred){
return function(){
deferred.resolve('return value from initial promise');
}
}
function someOtherPromise( ms ) {
var deferred = Q.defer();
setTimeout( resolver(deferred) , ms );
return deferred.promise;
}
function doSomething(data, cb){
console.log('----- doing something with:', data);
var val = "Did something with: " + data;
cb(val);
}
function reportProgress(doSomething, notifierCb){
notifierCb('waiting on it');
return function(someOtherPromiseResponse){
console.log('--- got promise response: ', someOtherPromiseResponse);
notifierCb('got response', someOtherPromiseResponse);
console.log('--- do something with it');
notifierCb('doing something with it');
doSomething(someOtherPromiseResponse, function(val){
notifierCb('done, result was:', val);
});
};
}
function notifier(update, detail){
console.log('Notifier update:', update, detail||"");
}
function logError(err){
console.log('ERROR:', err);
}
var iAmAPromise = someOtherPromise(1000).then(reportProgress(doSomething, notifier)).catch(logError);
console.log(' (Am I a Promise?)', Q.isPromise(iAmAPromise));
不过我可能误解了你的问题。
结果是:不,我不能。
看看为什么这可能不是一个好主意。