簡體   English   中英

Q Promise和Mongo DB Q.all

[英]Q promises and mongo db q.all

我正在調用mongodb數據庫-提取數據...讀取數據,然后根據該數據發出進一步的請求。 收到所有數據后,我希望對其進行處理。

我一直在使用Q.promises庫,但不知道我在做什么。 我以為q.all只會在一切完成后觸發? 但是,我的processPlaylist函數運行兩次。 我評論了下面的代碼:

謝謝,羅伯

var PlaylistCollection = require('./models/playlist');
var AssetCollection = require('./models/asset');
var screenID = '############';
var playerData = [];
// array continaing playlistys which have been synced
var alreadySynced = [];

// Process our playlist once downloaded
    var processPlaylist = function (playerData) {
    console.log('----Processing Playerlist-----')
    console.log(playerData);
    // DO STUFF
}


// Get playlist by id. Return playlist Data
var getSubLists = function (id) {
    return PlaylistCollection.findById(id);
}



// Get sub-playlist function

function getSubListRecursive(id) {

return getSubLists(id).then(function (playlist) {

    // store all our returned playlist data into a playlist array
    playerData.push(playlist)

    // an Array to keep tabs on what we've already pulled down
    alreadySynced.push(playlist.id)

    // get all our playlist.resources, and only return those which are unique
    var playlistResources = _.uniq(playlist.resources, 'rid');
    //  console.log('Playlist Resources: ', playlistResources)
    //  console.log(alreadySynced);
    var sublists = _.pluck(_.filter(playlistResources, { 'type': 'playlist' }), 'rid');
    // remove playlists which have already been synced. We don't want to pull them down twice
    sublists = _.difference(sublists, alreadySynced);
    //  console.log('sublists: ', sublists)

    // Get the next playlist and so on...
    var dbops = sublists.map(function (sublist) {
        // console.log(sublist)
        return getSubListRecursive(sublist)
    });

    q.all(dbops).then(function () {
        console.log('All Done - so process the playlist')
        return processPlaylist(playerData);
    });

})

}


// Trigger the whole process..... grab our first playlist / ScreenID
getSubListRecursive(screenID);

我得到以下輸出:

    ----Processing Playerlist-----
[ { _id: 554d1df16ce4c438f8e2225b,
    title: 'list 1',
    __v: 29,
    daily: true,
    endTime: '',
    startTime: '',
    resources:
     [ { rid: '55650cebef204ab70302a4d9',
         title: 'list 4',
         type: 'playlist' },
       { rid: '554d1df16ce4c438f8e2225b',
         title: 'list 1',
         type: 'playlist' } ] },
  { _id: 55650cebef204ab70302a4d9,
    title: 'list 4',
    __v: 1,
    daily: false,
    endTime: '',
    startTime: '',
    resources:
     [ { rid: '55650647ef204ab70302a4d8',
         title: 'list 3',
         type: 'playlist' } ] } ]
All Done - so process the playlist
----Processing Playerlist-----
[ { _id: 554d1df16ce4c438f8e2225b,
    title: 'list 1',
    __v: 29,
    daily: true,
    endTime: '',
    startTime: '',
    resources:
     [ { rid: '55650cebef204ab70302a4d9',
         title: 'list 4',
         type: 'playlist' },
       { rid: '554d1df16ce4c438f8e2225b',
         title: 'list 1',
         type: 'playlist' } ] },
  { _id: 55650cebef204ab70302a4d9,
    title: 'list 4',
    __v: 1,
    daily: false,
    endTime: '',
    startTime: '',
    resources:
     [ { rid: '55650647ef204ab70302a4d8',
         title: 'list 3',
         type: 'playlist' } ] },
  { _id: 55650647ef204ab70302a4d8,
    title: 'list 3',
    __v: 5,
    daily: false,
    endTime: '',
    startTime: '',
    resources:
     [ { rid: '55650637ef204ab70302a4d7',
         title: 'list 2',
         type: 'playlist' },
       { rid: '554d1df16ce4c438f8e2225b',
         title: 'list 1',
         type: 'playlist' },
       { rid: '55650cebef204ab70302a4d9',
         title: 'list 4',
         type: 'playlist' } ] } ]    

編輯

我寫的東西有些錯誤。 我與我的一個伙伴討論了該問題-他指出getSubListRecursive被遞歸調用多次,因此q.all語句被多次執行...

所以我重構了...

// Get sub-playlist function

function getSubListRecursive(id) {
    console.log(id)
    return getSubLists(id).then(function (playlist) {
        if (playlist) {
            // store all our returned playlist data into a playlist array
            playerData.push(playlist)
            // an Array to keep tabs on what we've already pulled down
            alreadySynced.push(playlist.id)
            // get all our playlist.resources, and only return those which are unique
            var playlistResources = _.uniq(playlist.resources, 'rid');
            //  console.log('Playlist Resources: ', playlistResources)
            //  console.log(alreadySynced);
            var sublists = _.pluck(_.filter(playlistResources, { 'type': 'playlist' }), 'rid');
            // remove playlists which have already been synced. We don't want to pull them down twice
            sublists = _.difference(sublists, alreadySynced);
            //  console.log('sublists: ', sublists)
            return sublists.map(function (sublist) {
                // console.log(sublist)
                if (sublists.length > 0) {
                    return getSubListRecursive(sublist)
                } else {
                    return processPlaylist(playerData);
                }
            });
        } else {
            return processPlaylist(playerData);
        }
    });
}

這可行。 我基本上是在使用Promise來控制此處的流程-這可能不是最好的方法嗎? 我不再使用all語句,最終導致數組中填充了所有播放列表數據-我可以在processPlaylist函數中對其進行操作。

但是,我還沒有將問題標記為已解決,因為我真的很想知道如何使用Q.all(正確使用promises)來做到這一點。

謝謝,羅伯

我認為您只是對整個過程何時完成感到困惑。 您需要等待,直到整個遞歸承諾鏈都解決了。 我認為您可以使用原始代碼,對processPlaylist()的調用位置稍作更改:

var PlaylistCollection = require('./models/playlist');
var AssetCollection = require('./models/asset');
var screenID = '############';
var playerData = [];
// array continaing playlistys which have been synced
var alreadySynced = [];

// Process our playlist once downloaded
var processPlaylist = function (playerData) {
    console.log('----Processing Playerlist-----')
    console.log(playerData);
    // DO STUFF
}


// Get playlist by id. Return playlist Data
var getSubLists = function (id) {
    return PlaylistCollection.findById(id);
}

// Get sub-playlist function
function getSubListRecursive(id) {
    return getSubLists(id).then(function (playlist) {
        // store all our returned playlist data into a playlist array
        playerData.push(playlist)

        // an Array to keep tabs on what we've already pulled down
        alreadySynced.push(playlist.id)

        // get all our playlist.resources, and only return those which are unique
        var playlistResources = _.uniq(playlist.resources, 'rid');
        //  console.log('Playlist Resources: ', playlistResources)
        //  console.log(alreadySynced);
        var sublists = _.pluck(_.filter(playlistResources, { 'type': 'playlist' }), 'rid');
        // remove playlists which have already been synced. We don't want to pull them down twice
        sublists = _.difference(sublists, alreadySynced);
        //  console.log('sublists: ', sublists)

        // Get the next playlist and so on...
        var dbops = sublists.map(function (sublist) {
            // console.log(sublist)
            return getSubListRecursive(sublist)
        });

        return q.all(dbops);
    });
}

// Trigger the whole process..... grab our first playlist / ScreenID
getSubListRecursive(screenID).then(function() {
    console.log('All Done - so process the playlist')
    return processPlaylist(playerData);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM