今日私は、再帰とネストされた約束を使用して約束を繰り返していたことを認識し、Q.all()
を正しく使用する方法を学びたいと思いました。私は一連の非同期関数を反復して、それらのすべてが解決するのを待ってから続行しようとしています。この現在の実装では、約束が解決されるのを待たずに、Q.allが直ちに返されます。ここでは反復機能のための私のコードreturn q.all()は、deferred.resolveでラップされていない限り、解決を待っていません
var updateNewReleasePlaylists = function() {
var self = this;
var promises = [];
var deferred = Q.defer();
// query for all users who have new releases
User.find({
$and: [{
'new_releases': {
$exists: true,
$ne: []
}
},
{
'refresh_token': {
$exists: true
}
}
]
}, 'new_releases',
function (err, users) {
if (err) {
throw new Error(err);
}
for (var i = 0; i < users.length; i++) {
console.log('when?')
promises.push(updatePlaylist(users[i]));
}
});
return Q.all(promises);
}
、ここではそれが呼び出している非同期関数である:
function updatePlaylist(user) {
var deferred = Q.defer();
User.findOne({'_id': user._id}, function(err, user) {
if (err) {
deferred.reject(err);
}
console.log(user);
deferred.resolve();
})
return deferred.promise;
}
私は次のように実装を変更した場合ので、それは完全に正常に動作します:
var updateNewReleasePlaylists = function() {
var self = this;
var promises = [];
var deferred = Q.defer();
// query for all users who have new releases
User.find({
$and: [{
'new_releases': {
$exists: true,
$ne: []
}
},
{
'refresh_token': {
$exists: true
}
}
]
}, 'new_releases',
function (err, users) {
if (err) {
throw new Error(err);
}
for (var i = 0; i < users.length; i++) {
console.log('when?')
promises.push(updatePlaylist(users[i]));
}
deferred.resolve(Q.all(promises)); // DIFFERENT
});
return deferred.promise; // DIFFERENT
}
これは私の言うことではありませんが、これを実装する方法は間違っていますが、最初に正しく取りたいと思います。何か助けがあれば、ここで私がupdateNewReleasePlaylists
という関数をテスト用に呼び出しています。
it('updateNewReleasePlaylists should properly resolve after all users playlists have been updated', function (done) {
this.timeout(60000);
testHelper.stageSpotifyUser(20)
.then(testHelper.stageSpotifyUser(20))
.then(testHelper.stageSpotifyUser(20))
.then(function() {
playlist.updateNewReleasePlaylists()
.then(function (promises) {
console.log(promises.length);
console.log('should be after');
done();
})
})
})
おかげさまでありがとうございました。
あなたは非同期的に( 'find'コールバックで)' promises'配列にプッシュしますが、 'Q.all'ではすぐにそれを使用します。もちろんそれはそこに空であり、すぐに成就する。あなたは 'User.find'を適切に約束し、' then'コールバックで配列と 'Q.all' * only *を使うべきです! – Bergi