2016-03-20 113 views
0

我想了解JQuery中的Promise。在下面的例子中我試圖加載一組從一個數組的網址後其加載,我想文本追加到HTMLjQuery的承諾:不執行然後api

array1 = ["helloworld.html", "helloworld.html", "helloworld.html"] 

loadData(array1).then(function() { 
    $('pre').append("done"); 
}); 


function loadData(gim) { 
    for (i = 0; i < gim.length; i++) { 
     console.log(i); 
     $.get(gim[i], function(data) { 
     console.log("a = " + i); 
     $('pre').append(data+" -- "+i+"<br>"); 
     }); 
    } 
    } 

但文本「做」不追加。 源代碼在http://plnkr.co/edit/EEaQqfnUyVHGZBgDCRPs?p=preview

+0

你需要從'loadData'返回承諾。請閱讀['$ q'文檔](https://docs.angularjs。org/api/ng/service/$ q) –

+0

你能解釋一下嗎 –

+0

這就是爲什麼有世界上的文檔和教程;)這是一種基本的,關於它的一個很好的文章,你可以找到[這裏](http: //markdalgleish.com/2013/06/using-promises-in-angularjs-views/)搜索「升級到承諾」。如果有什麼具體的,你不明白我會很樂意盡我所能解釋。 –

回答

1

我在這裏看到三個單獨的問題。

  1. 你的循環索引是錯誤的,當Ajax調用完成,因爲for環路異步Ajax調用完成之前自生自滅。
  2. 您需要找到一種方法,直到最後一次異步操作完成後再追加「完成」。你可以適當地使用承諾。
  3. 您的ajax結果不一定會按順序添加,因爲它不確定ajax調用的順序將會以什麼順序確定。根據服務器體系結構以及請求中涉及的內容,它們「可能」按請求的順序完成,但由於您並行運行它們,所以當然不能保證。

第一個問題是因爲操作是異步的,因此在異步操作完成時您的循環索引處於最終值。請參閱this answer以解決問題的這一部分。看到你的代碼在這裏實現的解決方案:http://plnkr.co/edit/cUFGZL0Bm6unRca3X7N5?p=preview

如果你想知道什麼時候所有的ajax操作完成,所以你可以附加「完成」,那麼你會想要正確使用承諾。你可以這樣做:

<script> 
    array1 = ["helloworld.html", "helloworld.html", "helloworld.html"] 

    loadData(array1).then(function() { 
     $('pre').append("done"); 
    }, function() { 
     // handle error here 
    }); 


    function loadData(gim) { 
     var promises = []; 
     for (var i = 0; i < gim.length; i++) { 
      (function(index) { 
      console.log(index); 
      promises.push($.get(gim[index]).then(function(data) { 
       console.log("a = " + index); 
       $('pre').append(data+" -- "+index+"<br>"); 
      })); 
      })(i); 
     } 
     return Promise.all(promises); 
     } 
    </script> 

工作例如:http://plnkr.co/edit/KrC7Lxu9OHs9suvNOC8t?p=preview

在這裏,你收集由$.get()返回到一個數組中承諾的數組,並使用Promise.all()告訴你,當所有這些承諾完成。

僅供參考,此代碼不保證結果將按順序附加,因爲異步操作可以按任何順序完成。


如果你想運行在並行的操作,但要確保它們在要求的順序添加,那麼你就可以改變你這樣的代碼來收集所有的結果,然後將結果添加到DOM爲了保證:

<script> 
    array1 = ["helloworld.html", "helloworld.html", "helloworld.html"] 

    loadData(array1).then(function() { 
     $('pre').append("done"); 
    }, function() { 
     // handle error here 
    }); 


    function loadData(gim) { 
     var promises = []; 
     for (var i = 0; i < gim.length; i++) { 
      promises.push($.get(gim[i])); 
     } 
     return Promise.all(promises).then(function(results) { 
      results.forEach(function(item, index) { 
      $('pre').append(item + " -- "+index+"<br>"); 
      }); 
     }); 
     } 
    </script> 

工作例如:http://plnkr.co/edit/nUHwFMg22V8rc9v12SqR?p=preview


如果只想使用jQuery承諾的功能(這是有點非標),你可以這樣做:

<script> 
    array1 = ["helloworld.html", "helloworld.html", "helloworld.html"] 

    loadData(array1).then(function() { 
     $('pre').append("done"); 
    }, function() { 
     // handle error here 
    }); 


    function loadData(gim) { 
     var promises = []; 
     for (var i = 0; i < gim.length; i++) { 
      promises.push($.get(gim[i])); 
     } 
     return $.when.apply($, promises).then(function() { 
      var results = Array.prototype.slice.call(arguments); 
      console.log(results); 
      results.forEach(function(item, index) { 
      $('pre').append(item[0] + " -- "+index+"<br>"); 
      }); 
     }); 
     } 
    </script> 

工作例如:http://plnkr.co/edit/IHMnEbYEFLjfguDkoubg?p=preview