2016-09-12 12 views
0

forループが次のループに進むのを待つ方法はありますか?ノードループの結果を待つための約束

userdetailsが実行され、realresult.playernameが渡される前に新しい変数に割り当てられていることを確認するにはどうすればよいですか?

コード:

return new Promise(function (resolve, reject) { 

    arr = []; 


    messages.find({convid: convid}).then(function(result) { 

     for(var a in result) { 
      realresult = result[a]; 

      userData.userDetails(realresult.userid).then(function (result) { 
       realresult.playername = result.username; 
      }); 
      userData.usercashinfo(realresult.userid).then(function (resulttwo) { 
       realresult.playerdetails = resulttwo; 
      }); 

      arr.push(realresult); 

     } 

     return resolve(arr); 
    }); 
}); 
+0

使用 'Promise.all' https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all –

+0

@Daniel_L私は知りませんどのように私はそれを動作させるために私の機能を作り直すだろう – maria

+0

[Javascriptのループの約束]の可能な複製(http://stackoverflow.com/questions/32701957/javascript-for-loop-promises) – Roberrrt

答えて

1

あなたはそれを解決するとき、解決の約束値の配列を返し、約束を書き込みしようとしています。ここで行うべき2つのことがあります:

  1. 約束を完了するのを待つために、returnを使用してください。約束のチェーンでは、return edでない限り、約束の価値を実際に解決するものはありません。
  2. 配列は、反復処理ではなく、約束を配列解決の際に配列にプッシュすることではなく、配列の配列として構成してください(message.find()の場合は、これを使用する必要があります)。
  3. Promise.all()を使用して約束オブジェクトを収集します。all()は、渡された約束がすべて解決された後にのみ返されます。
  4. (オプション)result変数名を複数のものに再利用しないでください。ここで間違っているわけではありませんが、不必要な混乱を招く可能性があります。一緒に入れて

、このようなものになりますので、私はそれが発電機と約束の組み合わせでそれを解決しようとして良いアイデアであると思っ

return messages.find(...).then(function(result) { 
    var promiseArr = []; 
    for (var a in result) { 
    promiseArr.push(
     promise.all([userData.userDetails(...), userData.usercashinfo(...)]) 
     .then(function(detailinfo) { 
     var realresult = result[a]; 
     var details = detailinfo[0]; 
     var cashinfo = detailinfo[1]; 
     realresult.playername = details.username; 
     realresult.playerdetails = cashinfo; 
     return realresult; 
    }); 
    } 
    return Promise.all(promiseArr); 
}); 
+0

ちょっと@yoz、私は私のポストを更新しました、あなたはその仕事をするためにいくつかの編集を行うことができますか? – maria

+0

@maria確かに、ここでサンプルコードを更新しました。 – yoz

0

を、私はその最高わからないんだけど行く方法は、しかし、その2つの組み合わせのための良い練習なので、私はそれを試してみました。

考えられるのは、ジェネレータ関数が新しい反復を開始する前にコールバック関数を待機しており、コールバック関数が両方の約束が完了するのを待ってから、ジェネレータ関数が反復処理を続けることを伝えることです。

here is a more simple example that I first tried on codepen

return new Promise(function (resolve, reject) { 
    arr = []; 
    messages.find({convid: convid}).then(function(result) { 
     function* iterations() { 
      for (var i = 0; i < result.length; i++) { 
       realresult = result[i]; 
       try { 
        var cbResult = yield cb(result[i].userid); 
        realresult.playername = cbResult.playername; 
        realresult.playerdetails = cbResult.playerdetails; 
        arr.push(realresult); 
       } catch (e) { reject(e) } 
      } 
      return arr.value; 
     } 

     var it = iterations(); 
     it.next(); 

     function cb(userid) { 
      Promise.all([ 
         userData.userDetails(userid), 
         userData.usercashinfo(userid) 
         ]).then(
          function(values) { 
           var realresult = {playername : values[0], playerdetails : values[1]} 
           returnValue = it.next(realresult); 
           if (returnValue.done) { 
            resolve(returnValue); 
           } 
          }, 
          function(e) { reject(e) } 
         ); 
     } 
    }); 
}); 
+1

['Promise'コンストラクタの反パターンを避けてください](http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

このコードはかなり畳み込まれており、エラーは処理されません。ジェネレータを使う代わりに 'async' /' await'のために行かなければなりません。 – Bergi

+0

http://prntscr.com/ch6i49あなたは@naortorのやり方をしましたが、単純な応答で配列を返しませんか? [0]と[1]のように? – maria

関連する問題