$ .each方法后调用函数

时间:2015-05-17 06:35:13

标签: jquery arrays asynchronous each

我在数组上使用$ .each方法将文件保存到本地文件夹。一旦.each方法完成了数组中的最后一个文件,我怎么能执行一个函数? .done方法不起作用。

 function downloadStartData() {
        $.each(startUpimageFilesArray,
            function (index, entry) {
                saveTofolder(entry.addy, entry.nameOfFile)
            });       
 };
 function saveTofolder(url, fileName) {
        try {
             WinJS.xhr({
                url: url,
                responseType: "blob",
             }).done(
                function writeBlobToFile(result) {
                var blob=result.response;
                var lFolder = Windows.Storage.ApplicationData; 
                var storeOption = Windows.Storage.CreateCollisionOption;
                lFolder.current.localFolder.createFileAsync(fileName, storeOption.replaceExisting
             ).then(function(file) {
               file.openAsync(Windows.Storage.FileAccessMode.readWrite
              ).then(function(output) {
                  var input = blob.msDetachStream();
                  Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output
               ).then(function () output.flushAsync(
                ).then(function () {
                   input.close();
                       output.close();
                  )};
               )};
             )};
          )};
        )};
  }
catch (e) {
    WinJS.log && WinJS.log("Exception while using XMLHttpRequest object 
    " + e, "sample", "error");
        }
};

3 个答案:

答案 0 :(得分:1)

each是同步的。

saveToFolder中有异步代码。您可以将回调传递给saveToFolder,而不是在当前迭代完成后调用。

function downloadStartData() {
    var len = startUpimageFilesArray.length;
    function callback() {
        len--;
        if(len==0) {
            // Write your "done" code here!
        }
    }
       $.each(startUpimageFilesArray,
           function (index, entry) {
               saveTofolder(entry.addy, entry.nameOfFile, callback)
           });       
};

// ... 
                ).then(function () {
                  input.close();
                      output.close();
                      callback(); 
                 )};
// ...

答案 1 :(得分:1)

调用代码必须有某种方法等待saveToFolder完成。你可以让它返回一个承诺:

function saveTofolder(url, fileName) {
        var deferred = $.Deferred();
        try {
             WinJS.xhr({
                url: url,
                responseType: "blob",
             }).done(
                function writeBlobToFile(result) {
                var blob=result.response;
                var lFolder = Windows.Storage.ApplicationData; 
                var storeOption = Windows.Storage.CreateCollisionOption;
                lFolder.current.localFolder.createFileAsync(fileName, storeOption.replaceExisting
             ).then(function(file) {
               file.openAsync(Windows.Storage.FileAccessMode.readWrite
              ).then(function(output) {
                  var input = blob.msDetachStream();
                  Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output
               ).then(function () output.flushAsync(
                ).then(function () {
                   input.close();
                       output.close();
                   deferred.resolve();
                  )};
               )};
             )};
          )};
        )};
  }
catch (e) {
    WinJS.log && WinJS.log("Exception while using XMLHttpRequest object 
    " + e, "sample", "error");
    deferred.fail();
        }
    return deferred.Promise();
};

现在,您可以使用jquery.each创建一个返回的承诺数组,而不是jquery.map

function downloadStartData() {
        var promises = $.map(startUpimageFilesArray,
            function (entry, index) {
                return saveTofolder(entry.addy, entry.nameOfFile)
            }); 
        return $.when(promises); // Returns a new promise that waits for all of them to complete   
 };

答案 2 :(得分:0)

saveToFolder 已完成 中最内在的 然后 功能可以做到这一点。您只需确认您的功能在完成所有保存后被称为 。因此,您可以传递另一个函数来指示当前已完成保存的是最后一个,如果是,则执行您的功能。

以下是如何操作的示例:

// add a new parameter "fnCompleted" to your saveTofolder
function saveTofolder(url, fileName, fnCompleted){ 
    // some other operation omited
    // below is the most inner then
    .then(function () {
         input.close();
         output.close();
         fnCompleted();
    });
}

function downloadStartData() {
    var allFilesCount = startUpimageFilesArray.length, completed = 0;
    function checkIfCompleted(){
        completed++;

        // if this is the last one, do the work
        if(completed >= allFilesCount){
            // do something
        }
    }

    $.each(startUpimageFilesArray,
        function (index, entry) {
            saveTofolder(entry.addy, entry.nameOfFile, checkIfCompleted)
    });
 };