2016-09-08 8 views
0

私はそれの中に約束した複雑なjavascript関数を持っています。ここで約束の実行を停止できません

私のコードです:

var chunkProjectList = function(list, project, accounts) { 
    return new Promise((resolve, reject) => { 
    // init delta 
    let delta = 5 
    if ((accounts.length * delta) > list.length) { 
     delta = (list.length/accounts.length) 
    } 
    // init chunked list 
    let chunkedList = [] 
    for (let i = 0; i < accounts.length; i++) { 
     chunkedList.push([]) 
    } 
    // loop on all users 
    for (let i = 0; i < list.length; i++) { 
     isInBlacklist(list[i], project.id) 
     .then(() => { // current user is in the blacklist 
     ProjectModel.deleteElementFromList(project.id, list[i]) 
     if (i === list.length - 1) { 
      // no screen_names available, cu lan 
      return resolve(chunkedList) 
     } 
     }) 
     .catch(() => { // we continue 
     let promises = [] 
     for (let j = 0; j < accounts.length; j++) { 
      promises[j] = FollowedUserModel.getFollowedUserByScreenName(list[i], accounts[j].id) 
     } 
     // we checked a screen_name for all accounts 
     Promise.all(promises) 
     .then((rows) => { 
      for (let k = 0; k < rows.length; k++) { 
      if (rows[k][0].length === 0 && chunkedList[k].length < delta && list[i] !== '') { 
       console.log('we push') 
       chunkedList[k].push(list[i]) 
       break 
      } 
      console.log('we cut (already followed or filled chunklist)') 
      if (k === rows.length - 1) { 

       // determine if is cancer screen_name or just filled chunklists 
       for (let l = 0; l < chunkedList.length; l++) { 
       if (chunkedList[l].length < delta) { 
        console.log('we cut because nobody wants ya') 
        ProjectModel.deleteElementFromList(project.id, list[i]) 
        ProjectModel.addElementToBlackList(project.id, list[i]) 
       } 
       if (l === chunkedList.length - 1) { 
        // you are all filled, cu lan 
        return resolve(chunkedList) 
        break 
       } 
       } 
      } 
      } 
      if (i === list.length - 1) { 
      // no screen_names available, cu lan 
      over = 1 
      return resolve(chunkedList) 
      } 
     }) 
     }) 
    } 
    }) 
} 

私のプログラムは、ユーザ名のリストにルーピング、および

例えば、アカウントごとに「デルタ」と呼ばれる限度で、口座間でそれを共有しようとしています: 私のリストには10​​00のユーザー名が含まれています。デルタは100で4つのアカウントがあります 予想される結果は、配列ごとに100個のユーザー名を含む配列の配列です。

chunkedList(アレイ)=>(配列1:長さ100、配列2:長さ100 ...)

私が持っている問題は、以下である:

デルタはすべてのために達するとchunkedList配列は、私はこの関数を終了し、内部のすべての作業を中止したいと思います。ちょうど私が解決する(chunkedList)を返します。

しかし、プログラムは引き続き実行され、パフォーマンスにとっては本当の問題です。

私はコードを理解することは難しいと知っています。ありがとう

+0

私はコードを簡単にスキミングしたことを認めます。あなたの記述に基づいて、関数の最上位に 'let abortFlag = false'を追加し、デルタに達したときに' true'に代入して、それが 'prom'リゾルバ関数で' if'チェックを追加するようにします。彼らはそれを見ると早く解決するのですか? – Katana314

+0

私は30分を過ごすことをお勧めします。それぞれが約束を返す別々の機能にリファクタリングする。そうすれば、私たちはそれについて簡単にコメントすることができます。 –

+0

のコードを読むのに少し時間がかかります。[Promiseコンストラクタ反パターン](http://stackoverflow.com/q/23803743/1048572)を避けて始めましょう! – Bergi

答えて

0

あなたのコードが達成しようとしていることを理解できません。しかし、コードをいくつかの別個の約束関数に分割することができるようです。これは明快に役立ち、実行を停止できるようにする必要があります。あなたのコードをテストすることができなければ、主な問題はあなたのメインループによって引き起こされたようです。あなたのコードでは、以下があります:あなたのメインの約束から

.then(() => { 
    .... 
    return resolve(chunkedList); 
} 

「戻る」文はここだけインナー.thenから復帰しようとしている()の呼び出しはありません。したがって、メインループは配列全体のコードをすべて実行し続けます。基本的に、ループはメインのPromiseの解決された値を変更し続け、ループ全体が完了するまで戻ってこないようです。

私のお勧めは、あなたのメインループの内容を、リストをパラメータとする別のメソッドに分割することです。このメソッドはPromiseを返します。このメソッドを使用すると、メインループを使用してPromise.all()を作成し、.catch()メソッドを追加できます。 catch()メソッドは、メソッド呼び出しの1つを拒否すると(残りのPromise.all配列内の残りの約束を完了しない場合)発生します。

上記の提案が意味をなさない場合はお詫び申し上げます。私はこれをすばやく書こうとしています。要約すると、メソッドの異なるステップを独自の約束を返す独自のメソッドに分割することができれば、約束事を非常に効果的に使用して、複数のタスクを連鎖させたり、並行して実行したり、

関連する問題