Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何知道在没有返回承诺的情况下成功执行了几个回调_Javascript - Fatal编程技术网

Javascript 如何知道在没有返回承诺的情况下成功执行了几个回调

Javascript 如何知道在没有返回承诺的情况下成功执行了几个回调,javascript,Javascript,!!!这个问题不是关于如何将承诺数组传递给when函数,因为file方法和onload返回承诺都不是重复的 我有一个自定义方法,它执行不返回承诺的异步函数。我的自定义方法确实返回了一个承诺。实现该功能的正确方法是什么?如例1所示使用超时,或如例2所示检查回调函数是否相等? 示例1: getAllFiles: function () { var def = $.Deferred(); var files = []; fileEntries.forEach(function(

!!!这个问题不是关于如何将承诺数组传递给
when
函数,因为
file
方法和
onload
返回承诺都不是重复的

我有一个自定义方法,它执行不返回承诺的异步函数。我的自定义方法确实返回了一个承诺。实现该功能的正确方法是什么?如例1所示使用超时,或如例2所示检查回调函数是否相等?
示例1:

getAllFiles: function () {
    var def = $.Deferred();
    var files = [];
    fileEntries.forEach(function(fileEntry){
        fileEntry.file(function (file) {
            var reader = new FileReader();
            reader.onload = function (e) {
                files.push({
                    name: fileEntry.fullPath,
                    content: e.target.result
                });
            };
            reader.readAsArrayBuffer(file);
        });
    });

    //this resolves the deffered    
    var interval = setInterval(function(){
       if (files.length === fileEntries.length) {
           def.resolve(files);
           clearInterval(interval);
       }
    }, 1000);

    return def.promise();
}
示例2

getAllFiles: function () {
    var def = $.Deferred();
    var files = [];
    fileEntries.forEach(function(fileEntry){
        fileEntry.file(function (file) {
            var reader = new FileReader();
            reader.onload = function (e) {
                files.push({
                    name: fileEntry.fullPath,
                    content: e.target.result
                });
                //this resolves the deffered
                if (files.length === fileEntries.length) {
                   def.resolve(files);
                   clearInterval(interval);
                }
            };
            reader.readAsArrayBuffer(file);
        });
    });

    return def.promise();
}
只需对每个异步函数(
onload
handler)做出承诺即可

(有必要对
中的参数执行
映射
ping操作,因为)

要回答您的实际问题:

实现该功能的正确方法是什么?如例1所示使用超时,或如例2所示检查回调函数中的相等性


从回调中执行。使用
setInterval
进行轮询的结果是不受欢迎的(它速度较慢,不会捕获错误,甚至在错误情况下也不会泄漏)。

看起来您正在使用jQuery,这意味着您可以利用它。请看@zzzzBov,我不知道在这里如何使用jQuery。你们能给我举个具体的例子吗?当
异步方法应该返回承诺时,给用户
,但无论是
文件
方法还是
onload
都不返回承诺。第二个示例是不正确的,因为您多次解析延迟的(实际上是在每次循环迭代中)。根据您的要求,计时器可能不够可靠。您是否尝试过维护一个计数器,并且仅在读取最后一个文件时才解决延迟问题?感谢您花时间进行响应,这让我对Jquery的defferds:)有了新的了解。但是有一个问题,为什么要从
文件
回调返回
def
,而不是
def.promise()
?您可以这样做。延迟的
实现
Promise
接口,当
使用该接口时,对其调用
.Promise()
只会构造另一个对象。谢谢。但是
def
可以在
getAllFiles
函数外部解析,对吗?如果我们返回
承诺
我们将阻止它。我也不明白为什么我需要这个
var files=$.map(参数,函数(args){returnargs[0];})因为参数已经包含对象数组。?我可以通过
返回Array.prototype.slice.call(参数)将其简单地转换为实际数组奇怪的是,当我像那样调用方法
getAllFiles().done(函数(文件){})
变量
files
只包含第一个对象,而不是
然后
返回的数组。知道为什么会发生这种情况吗?不,
def
无法在
getAllFiles
之外解决,因为我们不返回
def
,而是通过
$构建的承诺。这就是为什么在这里使用延期付款是省钱的原因。如果您将读取单个文件条目放在一个单独的函数中,那么您确实应该使用
.promise()
。如果不仅仅是为了减少混乱,这里也可能更干净:-)
getAllFiles: function () {
    var deferreds = fileEntries.map(function(fileEntry){
        var def = $.Deferred();
        fileEntry.file(function (file) {
            var reader = new FileReader();
            reader.onload = function (e) {
                def.resolve({
                    name: fileEntry.fullPath,
                    content: e.target.result
                });
            };
            reader.onerror = def.reject; // don't forget error handling!
            reader.readAsArrayBuffer(file);
        }, def.reject); // here as well
        return def;
    });
    return $.when.apply($, deferreds).then(function() {
        var files = $.map(arguments, function(args) { return args[0]; });
        return files;
    });
}