返回q.all()不等待解析,除非包装在deferred.resolve中

时间:2017-10-05 19:25:32

标签: javascript node.js promise q

所以今天我意识到我已经通过使用递归和嵌套的promises严重迭代承诺,并且想要学习如何正确使用Q.all()。我试图迭代一系列异步函数并等待所有这些函数在继续之前解决。在当前的实现中,Q.all立即返回,而不等待承诺解决。这是迭代函数的代码

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();
                    })
            })
    })

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

如果promises数组为空,那么获得返回似乎是正确的,因为没有什么可以等待的。当find()完成时,由于其异步性质,promises数组仍为空,因为尚未调用函数(错误,用户)。

所以,如果我认为find()是异步的,你应该返回整个User.find()或promise-wrap(如果需要)并返回它。