0

私は角度のあるアプリに取り組んでおり、問題が発生しています。私はJSにかなり慣れておらず、非同期プログラミングにも非常に慣れていないので、明らかな何かが欠けていると思います。

問題の要点は、配列を構築する for ループがあることです。次に、for ループが処理を完了したらすぐにその配列に参加する必要があります。通常、これは非常に簡単ですが、どうやらAngularでは for ループが非同期で実行されます。for ループが終了したに、配列の結合を強制する必要があります。

if(!data.results[i].is_deleted) {
  var objectsOnCurrentPermission = new Array();
  if(data.results[i].objects) {
    for(var j = 0; j < data.results[i].objects.length; j++) {
      var currentObjectId = data.results[i].objects[j].object_id;
      var currentObjectName;
      var objectData = Object.get({id: currentObjectId}, function(objectData) {
        objectsOnCurrentPermission.push(objectData.name);
        console.log('in loop in get fn');
        console.log(objectsOnCurrentPermission);
      });
    }
    console.log('after loop');
    console.log(objectsOnCurrentPermission);
    var listOfObjectsOnCurrentPermission = objectsOnCurrentPermission.join(', ');
    console.log('str after assignment');
    console.log(listOfObjectsOnCurrentPermission);
    data.results[i]['objects_list'] = listOfObjectsOnCurrentPermission;
}

驚いたことに、表示される出力を調べると (読みやすくするために「<」を追加しました)

after loop permissions.js:246
>Array[1]
permissions.js:247
str after assignment permissions.js:249

permissions.js:250
in loop in fn permissions.js:242
>Array[1]

after ループの出力が最初に実行されることがわかります。私が知る限り、最初に Array[1] を出力したとき、配列は実際には入力されていません.chromeは事後にそれを入力するだけです. 「str after assign」という行の後の空白行は、明らかに機能しなかった結合を出力しようとする場所です。そして、最後にループ内のコードが実行されます。前述したように、for ループが配列への入力を完了した後に、配列の結合が行われるようにする必要があります。

4

2 に答える 2

3

console.log()出力に基づくと、Object.get()関数は非同期である必要があるようです。つまり、関数を呼び出すと実行が開始され、しばらくしてから終了します。おそらく、終了すると、渡したコールバック関数を呼び出します。

したがって、最終結果の処理を完了するには、最後のObject.get()呼び出しが完了したとき、つまりすべてのObject.get()完了コールバックが呼び出されたときに、最終的なコードをトリガーする必要があります。残りの数を追跡する単純なカウンターは、それを行う簡単な方法の1つです。

すべてのメソッドがいつ完了したかを追跡し.get()、最終的なコードをトリガーする方法の基本的な考え方は次のとおりです。

if(!data.results[i].is_deleted) {
  var objectsOnCurrentPermission = [];
  if(data.results[i].objects) {

    // initialize counter so we know when all async functions are done
    var numRemaining = data.results[i].objects.length;

    for(var j = 0; j < data.results[i].objects.length; j++) {
      var currentObjectId = data.results[i].objects[j].object_id;
      var currentObjectName;
      var objectData = Object.get({id: currentObjectId}, function(objectData) {
        objectsOnCurrentPermission.push(objectData.name);
        console.log('get complete fn called');
        console.log(objectsOnCurrentPermission);
       --numRemaining;
       if (numRemaining === 0) {
          console.log('all get() functions done');
          console.log(objectsOnCurrentPermission);
          var listOfObjectsOnCurrentPermission = objectsOnCurrentPermission.join(', ');
          console.log('str after assignment');
          console.log(listOfObjectsOnCurrentPermission);
          data.results[i]['objects_list'] = listOfObjectsOnCurrentPermission;
       }
      });
    }
}
于 2012-12-04T04:53:02.850 に答える
0

同期/非同期コードのニーズを管理するために caolan の非同期ライブラリを使用することになりました。具体的には、async.parallel により、中間配列を構築し、先に進む前にそれらが完全であることを確認できました。https://github.com/caolan/async

于 2013-01-16T21:17:51.813 に答える