我可以在不创建延期的情况下报告Q承诺进度吗

Can I report Q promise progress without creating a deferred?

本文关键字:报告 承诺 情况下 创建 我可以      更新时间:2023-09-26

我正在通过调用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));

不过我可能误解了你的问题。

结果是:不,我不能。

看看为什么这可能不是一个好主意。