同时运行一个函数的多个实例

时间:2018-01-21 01:22:38

标签: javascript node.js function eventemitter

使用WebSocket我收到想要存储在mongodb数据库中的更新。每次发生更新时,都会发出包含数据的事件。数据是一个更新数组,需要在将它们放入数据库之前逐个处理。有时,在处理旧更新之前会收到新的更新。发生这种情况时,只处理和保存旧更新的一部分,并且该功能开始处理新数据。

有没有办法运行这个函数的多个实例,以便用新数据启动一个新函数不会停止处理旧数据?



eventBTRX.on('marketUpdate', function(data) {
	data.Sells.forEach(function(askChange) {
		console.log(askChange);
		switch (askChange.Type) {
			case 0:
				delete askChange.Type
				var askNew = {
					Quantity: askChange.Quantity,
					Rate: askChange.Rate,
					Type: 'ask',
					Exchange: 'BTRX'
				}
				dbo.collection(colName).insertOne(askNew, function(err, result) {
					if (err) console.log(err);
				});
				break;
			case 1:
				delete askChange.Type
				askChange.Type = 'ask';
				askChange.Exchange = 'BTRX';
				var deleteQuery = {Exchange: bidChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
				dbo.collection(colName).deleteOne(deleteQuery, function(err, result) {
					if (err) console.log(err);
				});
				break;
			case 2:
				delete askChange.Type
				askChange.Type = 'ask';
				askChange.Exchange = 'BTRX';
				var updateQuery = {Exchange: askChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
				var newValue = { $set: {Quantity: askChange.Quantity} };
				dbo.collection(colName).updateOne(updateQuery, newValue, function(err, result) {
					if (err) console.log(err);
				});
				break;
			default:
				console.log('Error in update type.')
		}
	});




1 个答案:

答案 0 :(得分:0)

如果您只是想确保某个特定消息中的项按照它们在data.Sells数组中出现的顺序插入,那么您可以使用async/await和数据库的promise接口这样:

eventBTRX.on('marketUpdate', async function(data) {
    for (let askChange of data.Sells) {
        console.log(askChange);
        switch (askChange.Type) {
            case 0:
                delete askChange.Type
                var askNew = {
                    Quantity: askChange.Quantity,
                    Rate: askChange.Rate,
                    Type: 'ask',
                    Exchange: 'BTRX'
                }
                await dbo.collection(colName).insertOne(askNew).catch(console.log);
                break;
            case 1:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var deleteQuery = {Exchange: bidChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                await dbo.collection(colName).deleteOne(deleteQuery).catch(console.log)
                break;
            case 2:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var updateQuery = {Exchange: askChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                var newValue = { $set: {Quantity: askChange.Quantity} };
                await dbo.collection(colName).updateOne(updateQuery, newValue).catch(console.log);
                break;
            default:
                console.log('Error in update type.')
        }
    }
});

如果您还想确保一条marketUpdate消息中的所有项目都插入到另一条消息之前,那么您可能需要创建一个这样的队列:

const marketUpdateQueue = [];

eventBTRX.on('marketUpdate', async function(data) {
    // put all .Sells items in the queue in order
    markedUpdateQueue.push(...data.map(item => item.Sells));
    // if we're already processing an item in the queue, then let it get processed first
    if (marketUpdateQueue.length > 1) {
        return;
    }
    // keep processing queue items until there are no more
    while (marketUpdateQueue.length) {
        let askChange = marketUpdateQueue[0];
        console.log(askChange);
        switch (askChange.Type) {
            case 0:
                delete askChange.Type
                var askNew = {
                    Quantity: askChange.Quantity,
                    Rate: askChange.Rate,
                    Type: 'ask',
                    Exchange: 'BTRX'
                }
                await dbo.collection(colName).insertOne(askNew).catch(console.log);
                break;
            case 1:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var deleteQuery = {Exchange: bidChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                await dbo.collection(colName).deleteOne(deleteQuery).catch(console.log);
                break;
            case 2:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var updateQuery = {Exchange: askChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                var newValue = { $set: {Quantity: askChange.Quantity} };
                await dbo.collection(colName).updateOne(updateQuery, newValue).catch(console.log);
                break;
            default:
                console.log('Error in update type.')
        }
        // remove the item we just processed
        marketUpdateData.shift();
    }
});

注意:这两种方法都需要一个错误处理策略(如果出现数据库错误,不确定您想要做什么)。原始问题中的代码只是记录并忽略了错误,因此这段代码也是如此。