2016-09-23 5 views
0

"getUsernameById"がループ内でジョブを完了する前に "then"が起動するという問題があります。ループ内でオブジェクトを非同期に変更してから変更したオブジェクトを返す

var dummyObject = { 
    choices: [ 
     { 
      votes: [ 
       "1234", 
       "2143", 
       "4321" 
      ] 
     } 
    ] 
}; 

Promise.each(dummyObject.choices, function(choice, i) { 
    dummyObject.choices[i].test = "test"; // this gets changed before 'then' 
    Promise.each(choice.votes, function(vote, j) { 
     getUsernameById(vote).then(function(username) { 
      dummyObject.choices[i].votes[j] = username; // this gets changed after 'then' 
     }); 
    }); 
}).then(function() { 
    res.json(dummyObject); 
}); 

これもできますか?

+0

'Promise.each'を提供するいくつかの約束ライブラリを使用している場合は、質問に名前を付けてください。ところで、あなたはここで、またはそこに 'リターン'を見逃していないと確信していますか? –

答えて

0

これはうまくいく可能性があります。私たちがthenと呼んでいるという事実によって証明されているgetUsernameByIdが約束を返しており、then自体が約束を返すということは、かなり進んでいます。だから我々がやっていることは、それぞれの選択に関連する各投票のためです。私たちは約束をpromises配列に入れています。これらの約束のそれぞれは、ユーザー名が取得され、正しい投票と選択肢が変更された後に解決されます。

約束配列にallを使用すると、promises配列内のすべての約束が解決された後に解決される約束が返されます。あなたの最後のthenは、これが起こった後にのみ起動します。この時点までにダミーオブジェクトを正しく更新する必要があります。

var dummyObject = { 
    choices: [ 
     { 
      votes: [ 
       "1234", 
       "2143", 
       "4321" 
      ] 
     } 
    ] 
}; 

var promises = []; 

dummyObject.choices.forEach(function (choice, i) { 
    choice.votes.forEach(function (vote, j) { 
    var userPromise = getUsernameById(vote).then(function (username) { 
     dummyObject.choices[i].votes[j] = username; 
    }); 

    promises.push(userPromise);   
    }); 
}); 

return Promises.all(promises).then(function() { 
    res.json(dummyObject); 
}); 

これが役に立ちます。何か疑問がある場合は教えてください。

関連する問題