Javascript 返回q.all(),除非包装为deferred.resolve,否则不等待解析

Javascript 返回q.all(),除非包装为deferred.resolve,否则不等待解析,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,因此,我今天意识到,我一直在使用递归和嵌套承诺来迭代承诺,这很糟糕,我想学习如何正确使用Q.all()。我正在尝试迭代一系列异步函数,并等待它们全部解析后再继续。在当前的实现中,Q.all将立即返回,而无需等待承诺得到解决。下面是我的迭代函数代码 var updateNewReleasePlaylists = function () { var self = this; var promises = []; var deferred = Q.defer(); /

因此,我今天意识到,我一直在使用递归和嵌套承诺来迭代承诺,这很糟糕,我想学习如何正确使用
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);

}
如果我像这样更改实现,它完全可以正常工作:

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
}

提前谢谢你的帮助

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


因此,如果我认为find()是异步的,那么您应该返回整个User.find()或promise wrap(如果需要)并返回它。

您是异步的(在
find
回调中!)推到
promises
数组,然后立即在
Q.all
中使用它。当然,它是空的,并立即满足。您应该正确提示
User.find
,并在
回调中使用数组和
Q.all
!是的,User.find是异步的。因此,在这个特定的用例中,可以将Q.all包装在deferred.resolve()中?我在网上看到的很多例子都没有做到这一点。我认为承诺包装没有错。有些lib可以做到这一点。如果我帮忙,请将我的回答标记为已接受。切士
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
}
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();
                    })
            })
    })