很难理解与Node.js的异步操作

时间:2014-10-09 14:13:42

标签: node.js

我正在开发一个小型Node应用程序,它是一个SQS队列的简单监听器,一旦接收到消息,代码将获取这些对象,解析它们然后将它们插入到DynamoDB中。

这是我到目前为止所做的:

var config = require('./config/config'),
    fs = require('fs'),
    sqsQueueURLs = config.sqs.urls,
    _ = require('underscore'),
    sqs = require('./lib/sqs'),
    dynamo = require('./lib/mildsaucedb'),
    async = require('async'),
    tasks = [];

config.sqs.queues.forEach(function(element, index) {
    tasks.push((function(callback) {
        var key = element.split("-").pop(),
            tableName = config.dynamo[key],
            params = {
                QueueUrl: config.sqs.urls[key],
                VisibilityTimeout: 60
            };

        sqs.receiveMessage(params, function(err, data) {
            if(err) console.log(err);

            if(data.Messages) {
                var message = data.Messages[0],
                    body    = JSON.parse(message.Body);

                dynamo.init(key, body, tableName);
                callback();
            }
        });
    }));
});

async.parallel(tasks, function(err, results) {
    console.log(err);
    console.log(results);
});

DynamoDb.js

"use strict";

var AWS = require('./aws'),
    DynamoDB = new AWS.DynamoDB(),
    _ = require('underscore'),
    errors = [], tblName;

var createActivity = function (obj) {
    DynamoDB.putItem({
        "TableName": tblName,
        "Item": {
            "UserId": { "N": obj.user_id.toString() },
            "CampaignId": { "N": obj.campaign_id.toString() },
            "Email": { "S": obj.email },
            "CustomActivityNodeId": { "N": obj.custom_activity_node_id.toString() }
        }
    }, function (err, data) {
        if(err) {
            errors.push(err);
        }
    });
};

var createAuthentication = function (obj) {
    DynamoDB.putItem({
        "TableName": tblName,
        "Item": {
            "UserId": { "N": obj.user_id.toString() },
            "CampaignId": { "N": obj.campaign_id.toString() },
            "Provider": { "S": obj.provider },
            "UID": { "S": obj.uid },
            "OauthToken": { "S": obj.oauth_token },
            "OauthTokenSecret": { "S": obj.oauth_token_secret },
            "Nickname": { "S": obj.nickname }
        }
    }, function (err, data) {
        if(err) {
            errors.push(err);
        }
    });
};

var createUser = function(obj) {

    if(_.has(obj, "authentication")) {
        createAuthentication(obj.authentication);
    }

    DynamoDB.putItem({
        "TableName": tblName,
        "Item": {
            "UserId": { "N": obj.user_id.toString() },
            "Identifier": { "S": obj.identifier },
            "ReferralToken": { "S": obj.referral_token },
            "CampaignId": { "N": obj.campaign_id.toString() },
            "FirstName": { "S": obj.first_name },
            "LastName": { "S": obj.last_name },
            "Gender": { "S": obj.gender },
            "BirthDate": { "S": obj.birthdate },
            "Username": { "S": obj.username },
            "MobileNumber": { "S": obj.mobile_number },
            "PostalCodeText": { "S": obj.postal_code_text },
            "Classification": { "S": obj.classification },
            "DeliveryEmail": { "B": obj.delivery_email },
            "DeliverySMS": { "B": obj.delivery_sms }
        }
    }, function (err, data) {
        if(err) {
            errors.push(err);
        }
    });
};

var dbMap = {
    'users': createUser,
    'activities': createActivity,
    'authentications': createAuthentication
};

var processErrors = function() {
    if(!_.isEmpty(errors)) {
        console.log(errors);
    }
}

module.exports = {
    init: function(qType, qObj, tableName) {

        if(_.isEmpty(qObj)) {
            errors.push("Object to insert is empty");
            return;
        }

        tblName = tableName;

        dbMap[qType](qObj);
        processErrors();
    }
}

但我无法获得一致的结果。似乎脚本“挑选并选择”哪个队列命中它而不是在不同的时间点击每个队列。

1 个答案:

答案 0 :(得分:0)

SQS不保证FIFO。你可能会遇到问题。 http://aws.amazon.com/sqs/faqs/