为什么我的承诺没有得到解决?

问题描述:

我有两个功能 - 用于下载文件辅助函数是如下为什么我的承诺没有得到解决?

var downloadHelper = function(url, saveDir) { 
    var deferred = Q.defer(); 

    setTimeout(function() { 
     deferred.resolve("success");  
    }, 2000); 


    return deferred.promise; 
} 

现在我有一个文件列表并行下载。我有这个功能的逻辑如下:

var downloadAll = function() { 
    var fileDownloadList = [] 
    for(var key in config.files) { 

     var deferred = Q.defer(); 
     var saveLocation = __base + config.localDir 
     downloadHelper(
      config.files[key], 
      saveLocation 
     ).then(function() { 
      deferred.resolve("downloaded: " + fileUrl); 
     }).catch(function(err) { 
      deferred.reject(err); 
     }); 

     fileDownloadList.push(deferred.promise); 
    } 

    Q.all(fileDownloadList).done(function() { 
     console.log("All downloaded"); 
    },function(err) { 
     console.log(err); 
    }); 

    setTimeout(function() { 
     console.log(fileDownloadList); 
    }, 10000); 
} 

完成永远不会被调用!

为了调试的目的,我添加了一个setTimeout,将在10秒后调用,我看到的是2个文件中的第二个promise被解析,第一个仍处于挂起状态。

任何想法?

在此先感谢

+1

你严重滥用承诺。您应该将'downloadHelper'返回的那个直接推入您的数组中,而不是不必要地承诺承诺中的承诺。 – meagar

+1

下载中的延迟对象在for循环的每次迭代中,都会被覆盖。所以,只有最后一个将得到解决 –

+0

@JaromandaX但是我不是创建一个新的延迟对象'var deferred = Q.defer()'? – harryjohn

一种方法让你的代码工作

for(var key in config.files) { 
    (function() { 
     var deferred = Q.defer(); 
     var saveLocation = __base + config.localDir 
     downloadHelper(
      config.files[key], 
      saveLocation 
     ).then(function() { 
      deferred.resolve("downloaded: " + fileUrl); 
     }).catch(function(err) { 
      deferred.reject(err); 
     }); 
     fileDownloadList.push(deferred.promise); 
    }()); 
} 

但由于downloadhelper返回一个承诺,没必要再创建一个一个

for (var key in config.files) { 
    var saveLocation = __base + config.localDir 
    fileDownloadList.push(downloadHelper(
     config.files[key], 
     saveLocation 
    ).then(function() { 
     return("downloaded: " + fileUrl); 
    })); 
} 

你会看到我删除了

.catch(function(err) { 
    deferred.reject(err); 
}) 

这是多余的,这是一样的没有捕获