javascript
  • jquery
  • asynchronous
  • 2016-01-21 106 views 2 likes 
    2

    如何在完成所有3個異步請求後確保執行self.loadable()。 ???如何確保在完成3個異步功能後執行同步功能

    var imghtml = "<span class='pull-right' style='padding-right:25px'><img alt='track' src='app/images/Icons/Track.png'><img alt='expand' src='app/images/Icons/Expand.png'></span>"; 
    
          var request1 = {}; 
          if(self.serviceid != null) 
           request1.healthIssue = {id:self.serviceid}; 
    
          request1.location = {id:self.locationid}; 
          request1.time = {id:header.defaultduration().value}; 
          request1.hospital = {id:header.defaulthospital().value}; 
          request1.query = {groupName:'speciality', dimension:'VISITS', viewBy:'MARKETSHARE'}; 
    
          console.log(request1); 
    
          server.fetchData(request1).done(function(data){  
    
           console.log('The specialty marketshares are : '); 
           console.log(data); 
    
           if(data.length != 0) { 
            $.each(data, function(index,mshare){ 
             var count = 0; 
             $.each(self.marketsharetable(), function(index, tobj) { 
              if(tobj.specialty == mshare.name){ 
               tobj.marketshare(mshare.value); 
               count++; 
               return false; 
              } 
             }); 
             if(count == 0){ 
              var obj = {}; 
              obj.specialty = mshare.name; 
              obj.marketshare = ko.observable(mshare.value); 
              obj.rank = ko.observable(); 
              obj.volume = ko.observable(); 
              obj.btns = imghtml; 
    
              self.marketsharetable.push(obj); 
             } 
    
            }); 
            console.log(self.marketsharetable()); 
           } 
           else{ 
            console.log("Clearing the table"); 
            $('#msharetable').DataTable({ 
             "paging": false,     
             "info":  false, 
             "destroy": true, 
             "data": self.marketsharetable(), 
             "language": { 
              "emptyTable": "No data available" 
             } 
            }); 
           } 
    
          }); 
    
          var request2 = {}; 
          if(self.serviceid != null) 
           request2.healthIssue = {id:self.serviceid}; 
          request2.location = {id:self.locationid}; 
          request2.time = {id:header.defaultduration().value}; 
          request2.hospital = {id:header.defaulthospital().value}; 
          request2.query = {groupName:'speciality', dimension:'VISITS', viewBy:'RANK'};   
    
          server.fetchData(request2).done(function(data){    
           console.log('The specialty ranks are : '); 
           console.log(data); 
    
           $.each(data, function(index,mrank){ 
            var count = 0; 
            $.each(self.marketsharetable(), function(index, tobj) { 
             if(tobj.specialty == mrank.name){ 
              tobj.rank(mrank.value); 
              count++; 
              return false; 
             } 
            }); 
            if(count == 0){ 
             var obj = {}; 
             obj.specialty = mrank.name; 
             obj.marketshare = ko.observable(); 
             obj.rank = ko.observable(mrank.value); 
             obj.volume = ko.observable(); 
             obj.btns = imghtml; 
    
             self.marketsharetable.push(obj); 
            } 
    
           }); 
           console.log(self.marketsharetable()); 
    
    
          }); 
    
          var request3 = {}; 
          if(self.serviceid != null) 
           request3.healthIssue = {id:self.serviceid}; 
          request3.location = {id:self.locationid}; 
          request3.time = {id:header.defaultduration().value}; 
          request3.hospital = {id:header.defaulthospital().value}; 
          request3.query = {groupName:'speciality', dimension:'VISITS', viewBy:'COUNT'};   
    
          server.fetchData(request3).done(function(data){    
           console.log('The specialty input volumes are : '); 
           console.log(data); 
    
    
           $.each(data, function(index,mvolume){ 
            var count = 0; 
            $.each(self.marketsharetable(), function(index, tobj) { 
             if(tobj.specialty == mvolume.name){ 
              tobj.volume(mvolume.value); 
              count++; 
              return false; 
             } 
            }); 
            if(count == 0){ 
             var obj = {}; 
             obj.specialty = mvolume.name; 
             obj.marketshare = ko.observable(); 
             obj.rank = ko.observable(); 
             obj.volume = ko.observable(mvolume.value); 
             obj.btns = imghtml; 
    
             self.marketsharetable.push(obj); 
            } 
    
           }); 
           console.log(self.marketsharetable()); 
    
    
           $('#msharetable').DataTable({ 
            "paging": false,     
            "info":  false, 
            "destroy": true,      
            "data": self.marketsharetable(), 
            "language": { 
             "emptyTable": "No data available" 
            }, 
            "deferRender": true, 
            "columns": [ 
               { "data": "specialty" }, 
               { "data": "marketshare" }, 
               { "data": "rank" }, 
               { "data": "volume" }, 
               { "data": "btns" } 
            ]     
           }); 
    
          }); 
          self.loadtable(); 
    

    請幫助如何在3個異步調用服務器之後執行同步功能。對於高級JavaScript來說是新的。建議請問?

    +2

    我認爲你可以使用承諾來做到這一點,看看這個:https://developer.mozilla。org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all – jolmos

    回答

    1

    在JavaScript中,當您調用一個scynchronous函數時,它通常會返回一個promise。正如我在代碼中看到的,您的server.fetchData(request)調用會返回承諾,因爲您使用的是承諾中典型的.done

    您可以將承諾存儲在一個變量,像這樣:

    var promise1 = server.fetchData(request); 
    

    再後來用它像這樣:

    promise1.done(function() { /* your code here */ }); 
    

    內所做的承諾被滿足時,將運行中的作用。履行(或拒絕)承諾的責任在異步方法內。即當請求結束並且響應已到達時,異步方法將履行承諾。而且,INT他的情況下,將通過提供給回調即

    promise.done(function(response) { /* use response here */}); 
    

    響應,您可以瞭解更多有關的承諾看jQuery docs on deferred(這是實現承諾的jQuery的方式)或谷歌搜索「JavaScript的承諾」兌現它。延遲具有promise的所有功能,以及用於履行(resolve)或拒絕(reject)該承諾的方法,可以返回調用延遲的.promise()方法。

    例如一個asynchronouse方法couldlook這樣的:

    function asynch() { 
        var deferred = $.Deferred(); 
        // do something asynchronous, and get some data 
         // if the result is ok, fulfill the promise 
         deferred.resolve(data); 
         // if it failed, reject it 
         deferred.reject(reason); 
        return deferred.promise(); 
    }; 
    

    的想法是,如果你調用這個方法,它會返回inmediately承諾。而且,當異步代碼(如AJAX調用)結束時,返回它的方法將會保證爲rejectresolve。發生這種情況時,將會調用附加到承諾的donefail回調。

    現在您已經瞭解了這些基礎知識,jQuery提供了一種編寫承諾的方法,即jQuery.when()。你可以這樣寫代碼:如果三個承諾是fulfilled.If其中任何一個失敗,它不會運行在所有

    var promise1 = server.fetchData(request1); 
    var promise2 = server.fetchData(request2); 
    var promise3 = server.fetchData(request3); 
    
    $.when(promise1, promise2, promise3) 
        .done(function(result1, result2, result3) { 
        // use the results of the three server.fetchData here 
        }) 
    

    的完成部分將只運行。

    您應該始終處理您的承諾的.fail。 A server.fetchData可能因爲幾個原因失敗,並且您的代碼應該處理這些問題。

    還有另一個有趣的諾言庫,like Q,它們在現代瀏覽器中本地支持:native promises。他們都分享了Promises/A+中定義的基本概念。

    +0

    謝謝JotaBe提供了一個快速而整潔的答案。 @JotaBe –

    相關問題