如何知道几个回调是否成功执行而没有返回的承诺

时间:2014-08-20 15:11:14

标签: javascript

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

我有一个自定义方法,它执行不返回promises的异步函数。我的自定义方法确实返回了一个promise。实现该功能的正确方法是什么 - 使用示例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();
}

1 个答案:

答案 0 :(得分:1)

只需为每个异步函数(onload处理程序)创建承诺然后!

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;
    });
}

(对map中的参数进行then ping是必要的,因为jQuery's $.when result is so ugly

回答你的实际问题:

  

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

从回调中做到这一点。 setInterval的轮询结果被鄙视(它更慢,在错误情况下不会发现错误甚至泄漏)。