簡體   English   中英

貓鼬findOneAndUpdate()阻止socket.io請求?

[英]Mongoose findOneAndUpdate() blocking socket.io requests?

我不確定是否存在某些我不理解的問題或某種錯誤,但我只是無法弄清楚。 基本上,有時我會從服務器向API發送請求以獲取一些信息,然后將其保存到數據庫中,但是每當保存數據時,socket.io請求都會被阻塞,並且僅當所有數據都被阻塞時已更新是其他請求一堆通過時。 我知道他們被阻止了,因為我試圖在數據更新時每100毫秒發送一次聊天消息,並且只有當API中的最后一條信息被保存時,消息才全部通過,而消息卻沒有通過保存。 如何確保它不會阻止其他請求?

這是我測試時的控制台輸出示例:

...
New chat message received
New chat message received
New chat message received
New chat message received
UPDATING 1455 ITEMS
UPDATED ALL PRICES, TOOK 3592
New chat message received
New chat message received
New chat message received
New chat message received
...

碼:

request('url')), (err, response, body) => {
        let items = JSON.parse(body);
        let startTime = new Date().getTime();
        console.log(`UPDATING ${items.prices.length} ITEMS`);

        for (let i = 0; i < items.prices.length; i++) {
            const item = items.prices[i];

            Prices.findOneAndUpdate({item: item.name}, {$set: {price: item.price, last_update: Date.now()}}, (err, res) => {
                if(!res){
                    newPrice = new Prices({
                        item: item.name,
                        price: item.price
                    });

                    newPrice.save((err, saved) => {
                        if (err) {
                            console.log(err);
                        }
                    })
                }

                if(i == items.prices.length - 1){
                    console.log(`UPDATED ALL PRICES, TOOK ${new Date().getTime() - startTime}`);                    
                }
            });
        }
});

不確定這是否對您有幫助,但是這是處理接收消息的代碼:

socket.on('sendMessage', (data) => {
    User.findOne({id: socket.request.user.id}, (err, user) => {
        if (err) throw err;

        //Check if the user is muted and if not, proceed
        if(user.mutedUntil < Date.now()){
            User.findOneAndUpdate({id: socket.request.user.id}, {$set: {lastMessageDate: Date.now()}}, (err, dbUser) => {
                if (err) throw err;

                let parsed = ParseMessage(data.message);                     

                if(parsed.command === 'none'){
                    SendMessage(dbUser, socket, data);
                }else{
                    commandData = {parsed: parsed, socket: socket}
                    ExecuteChatCommand(commandData);
                }
            });
        }else{
            socket.emit('serverMessage', {
                type: 'error',
                title: 'You\'re muted',
                message: 'You are muted and can\'t chat until ' + user.mutedUntil
            });
            console.log('Muted user tried chatting');
        }
    });       
});

您的for循環正在執行阻塞操作,因為它是同步操作。

您應該考慮改用Promises 除了使用Promise.map or Promise.all循環之外,還for使用Promise.map or Promise.all中的Promise.mapPromise.all或ES6中的Promise.all來實現相同目的,但是要采用異步方式。

對於您的查詢,您可以使用mongoose .exec()將其轉換為完整的Promise

注意 :您正在嘗試在for循環中查找和更新1455次...也許在Bluebird中查看Promise.mapSeries ,以便Promises不會同時發送到Mongo,而是以串行方式發送

暫無
暫無

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

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