2015-12-09 4 views
5

$q.allのように何をすればよいですか?同時に実行される約束の数は制限されていますか?

私の質問は、私が欲しいHow can I limit Q promise concurrency?

せいぜい5つのプロセスは、他の質問のための受け入れ答えはで動作するように包まれpromiseのために書かれたライブラリです時間

で生み出されていないだけのようですQ。 しかし、具体的には、QではなくAngularの$qのソリューションに興味があります。

背景:問題が解決されます。a)URL bを取得します)ファイルをダウンロード:
私は2つの段階にダウンロードするファイルの束を持っています。
ブラウザでは同時に取得できるファイル数が制限されているため、$q.allという約束をそのまま使用すると、すべてのダウンロードがオフになります。
N のみがすぐに実行されます。 Chromeの、残りは遅れています。 Max parallel http connections in a browser?を参照)
問題は、ブラウザが N + 1 番目のファイルのダウンロードを実行することにより、時間ので、URLが有効でなくなっている、URLが有効期限を持っているということではありません。
だから、私はあなたが再帰的な何かをすることができると思いthrottled.all(6, promises)ではなく$q.all(promise)

答えて

0

のような何かをしたいです。

これにより、ちょうど$qを使用できます。あなたはちょうどあなたが使用されるだろう、リストを持っている必要があり、あなたが$q.all

self.MakeCall = function(theList, chunkSize){ 
    //Split list into what will be processed and what should be held 
    var processList = theList.slice(0,chunkSize); 
    var holdList = theList.slice(chunkSize); 

    return $q.all(processList).then(function(result) { 
     //If holdList is empty you are finished 
     if(holdList <= 0) { 
     return result; 
     } 
     else { 
     //More items make recursive call to process next set 
     return self.MakeCall(holdList, chunkSize); 
     } 
    }); 
    }; 
//Initialize Recursive call 
self.MakeCall(self.contacts); 
+1

悪いスタートではない、@マーカス、ありがとう。 あなたの例がサイズNのチャンクに分割されているので、常にNの約束を実行するのではなく、並行して並行しているわけではありません。 :) – Daryn

0

のためにとにかく必要がある。ここ同時チャンクを実行する代替ソリューションであるだろう。それは他の答えほどきれいではありませんが、あなたが探しているものに近いです。

私は検証のためにいくつかのマークアップを残しました。

self.list [...]; 

self.MakeCall = function(theList, chunkSize,methodTracker){ 
    //Set default chunkSize 
    chunkSize = (chunkSize)?chunkSize:1; 

    //Slice list using previously defined list 
    // so multiple instances can be runuse same list 
    var processList = self.list.slice(0,chunkSize); 
    self.list = self.list.slice(chunkSize); 

    return $q.all(processList).then(function(result) { 
     //If holdList is empty you are finished 
     if(self.list <= 0) { 
     console.debug("method last: " + methodTracker); 
     return result; 
     } 
     else { 
     //More items make recursive call to process next set 
     console.debug("method: " + methodTracker); 
     return self.MakeCall(self.list, chunkSize,methodTracker); 
     } 
    }); 
    }; 
    //Initialize Recursive call 
    self.MakeCall(self.list,1,1).then(function() { 
    console.warn('end 1'); 
    }); 
    //Initialize Second call that will run asynchronous with the first 
    // this can be initialized as many times as you want concurrent threads 
    self.MakeCall(self.list,1,2).then(function() { 
    console.warn('end 2'); 
    }); 

私は別の答えに置くことにしました。私は2つは私がこれを行うには、いくつかの異なる方法を試みたが、最終的にとの$q.all振る舞いを拡張$qへの拡張を書くことに定住し、他の

0

に変更を加えたいと思わなかったことを十分に異なっていると思います$q.allLimit()

詳細については、angular-q-limitモジュールを参照してください。

モジュールは、Promisesの配列を受け取り、すべてが使い果たされるまで順序付きの順序で(実行を限度に制限して)実行するラップ関数を作成することによって動作します。そして、それ自身の約束をすべての戻り値で$q.all()と同じ方法で解決します。

+0

あなたのライブラリーへのリンクを貼り付けるのではなく、どのように動作するかを詳しく述べてください。 – Bergi

+1

それは理にかなっていません。 [それは不可能です](http://stackoverflow.com/q/30823653/1048572)、 'all'をシーケンスします。 – Bergi

+0

お詫び申し上げます。私はここにいくつかの例を追加しました - https://gist.github.com/hash-bang/652be06e3cf89f9d71fa2dfceb893719 - あなたが何を要求しようとしているのかを具体的にすることができれば、何かを書くことができます。 –

0

「すべての」約束の解決は無関係です(ページ上のいくつかの要素を更新していて、プログレッシブであればwhooshには関係ありません)。私は単純なTaskQueueサービスを作成しました。それはすべての約束が解決されるのを待つのではなく、それが得たすべての追加された約束/機能/タスクを処理します。設定された限界値の並行性。

私はこの問題と私の問題を助けてくれない他のいくつかのStackOverflowsしか見つけられませんでした。だから私は今私が推測するコミュニティに何かを戻します。誰かを助けることを願っています。

constやlambda式のような現代的なJSのものを使用していますが、単に古いものが必要な場合は、単にbabelのようなプリコンパイラからコンパイルすることができます。

https://gist.github.com/Blackskyliner/8b1bafed326044fa4f8b1ba2627d1117

それは単に約束または値を返すだけ匿名関数されているタスク、後にそのキューを処理し、追加されます。これは、サービス上の設定可能な 'maxConcurrentTasks'変数に準拠します。

タスクが約束などを返す約束を返した場合、タスクは常にキュー内の最初の「スロット」を使用します。したがって、Task Promiseチェーン全体が解決された(または拒否された)後に、追加された他のタスクの「スロット」を解放します。

関連する問題