2016-05-02 7 views
1

一連のプロミスを同期して実行し、最初のプロミスが完了するまで2回目のプロミスが実行されないようにするにはどうすればよいですか?ここでは、3つのチャンクをロードしています。それぞれのクライアントは10の長さで、残りはロードします。ここでのアイデアは、残りの部分がロードされている間に最初のN個のクライアントを表示することです。フラット化同期角度プラン

私が望ましくないことは、以下のように、processChunk1()、then(()=> processChunk2())などを明示的に言う必要があることです。クライアントがなくなるまでループ内でチャンクを処理したい。どんな助けもありがとう!それを行うには

loadPerformanceDtos(): ng.IPromise<{}> { 
    var deferred = this.$q.defer(); 
    var clientList: any = []; 

    $.extend(clientList, this.$location.search().client); 

    // If the user only searched for one client, we need to turn it into an array 
    if (!angular.isArray(clientList)) { 
     clientList = [clientList]; 
    } 

    var that = this; 

    // Sort so we can chunk it 
    var sortedClients: string[] = (<string[]>clientList).sort(); 
    const chunkSize: number = 10; 

    // Reset page's data 
    this.performanceDtoModels = []; 

    // Set up three chunks to load in order 
    var chunk1: string[] = sortedClients.splice(0, chunkSize); 
    var chunk2: string[] = sortedClients.splice(0, chunkSize); 
    var chunk3: string[] = sortedClients.splice(0, chunkSize); 

    // I don't want to have to explicitly define the groups below, I want this to be in a loop 
    processChunk(chunk1).then(() => { 
     // Resolve the inital page's progress bar 
     deferred.resolve(); 

     processChunk(chunk2).then(() => { 
      processChunk(chunk3).then(() => { 
       processChunk(sortedClients); 
      }); 
     }); 
    }); 

    function processChunk(chunk: string[]) { 
     var chunkDeferred = that.$q.defer(); 
     if (chunk.length === 0) { 
      chunkDeferred.resolve(); 
     } else { 
      that.performanceService.loadPerformanceData(chunk) 
       .success((data: IPerformanceDtoModel[]) => { 
        data.forEach((item: IPerformanceDtoModel) => { 
         // Add the final item to the page 
         that.performanceDtoModels.push(item); 
        }); 

        chunkDeferred.resolve(); 
       }); 
     } 
     return chunkDeferred.promise; 
    } 

    return deferred.promise; 
} 

答えて

1

一つの方法は、各非同期操作が完了した後、元のリストのスライスに自分自身を呼び出す再帰関数を使用することです。以下は実装例です。 processChunksは、各非同期操作の後に自身を呼び出します。

この実装では、非同期メソッドが失敗した場合を考慮していません。すべてのチャンクがいつ読み込まれたかを知る方法はありません。後者の場合は、最後のチャンクがロードされた時点を判断するロジックを追加する必要があります。

class YourClass { 

    loadPerformanceDtos(): ng.IPromise<{}> { 
     this.loadDeferred = this.$q.defer(); 

     var requestedClients: string|string[] = this.$location.search().client; 

     var clientList: string[]; 
     if (!angular.isArray(requestedClients)) { 
      clientList = [requestedClients]; 
     } else { 
      clientList = requestedClients; 
     } 

     clientList.sort(); 
     this.performanceDtoModels = []; 
     this.processChunks(clientList, 10); 
    } 

    processChunks(list: string[], size: number) { 
     var chunk = list.slice(0, size); 

     // Resolve the initial page's progress bar 
     if (this.performanceDtoModels.length > 0) { 
      this.loadDeferred.resolve(); 
     } 

     if (chunk.length > 0) { 
      this.processChunk(chunk).then(() => { 
       this.processChunks(list.slice(size), size); 
      }); 
     } 

    } 

    processChunk(chunk: string[]) { 
     var deferred = this.$q.defer(); 

     if (chunk.length === 0) { 
      deferred.resolve(); 
     } 
     else { 
      this.performanceService.loadPerformanceData(chunk) 
       .success((data: IPerformanceDtoModel[]) => { 
        data.forEach((item) => { 
         this.performanceDtoModels.push(item); 
        }); 

       deferred.resolve(); 
      }); 
     } 

     return deferred.promise; 
    } 
} 
+0

これは私が必要としていたものです。私は意図的に簡潔にエラー処理を省略し、それを自分で処理することができます。私が見つけたすべてのリソースは、あなたが有望な数の有望チェーンを持っていることを期待しているので、それを一般化するためのある方向性が必要でした。 – user2339814