如何控制NodeJS中的应用程序流

时间:2017-05-29 16:23:18

标签: javascript php node.js asynchronous synchronous

我在nodeJS中编写了我的第一个应用程序。我正在写一个电报机器人,我想知道如何控制应用程序的流程,因为它具有异步性质。我来自php背景,一切都很简单,程序化,一个接一个。

让我们说,在我的机器人中,当收到任何消息时,首先程序必须确保用户详细信息在缓存或数据库中,然后再继续。检查完成后,可以继续。

我打算通过使用变量作为标志来实现这一点,但由于javascript的异步特性,它无法完成。我不知道该怎么做。我是否将侦听器分配给对象并发出事件来控制流程?

这是我的代码

    const fs = require('fs');

// Establish connection with cache and database
const mysql = require('mysql-wrapper');
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');
const bb = require('bot-brother');

var settings = {
    host: 'localhost',
    database: 'test',
    user: 'root',
};
var qb = require('node-querybuilder').QueryBuilder(settings, 'mysql', 'single');

//Load the database cache functions
const dbc = require("./dbc");
dbc.memcached = memcached;
dbc.mysqc = qb;

//Load the user handling functions 
const user = require("./user");
user.dbc = dbc;

const bot = bb({
    key : '331263599:AAHmLl4Zcg4sKGnz7GNzacgkJl1W8lwz33c',
    polling: { interval: 0, timeout: 1 }
});

//code that checks user existence in cache/db
bot.api.on('message', (msg)=>{
    console.log(msg.from);
    var userData = msg.from;
    var tid = userData.id;
    //Check if user is in cache 
    user.check_user_existence(tid,function(re){
        if(re < 2){
            user.complete_user_existence(re,userData,function(err,response){
                if(err){
                    bot.api.sendMessage(tid,"Sorry an unexpected error occured!");
                } else {
                    console.log('ha');
                    play = 1;
                }
            });
        } 

    });
});


//Code to be run after checking 
if(play==1){
    send_another_message();
    do_some_things();
}

2 个答案:

答案 0 :(得分:1)

您可以使用回调或承诺 您可以使用异步模块或互斥锁

如果需要序列化一些异步函数,可以使用以下方法之一:

Callback

Native promises

Bluebird promise

Async module

回调和承诺主要用于第二个功能需要第一个功能的相关功能.bluebird是一个用于创建承诺并具有完全自定义功能的模块。

异步模块是异步运行函数并将它们的结果组合在一起的好方法。

最后一种方式是Mutex,如果您在单个对象或文件中进行异步写入,则需要锁定释放方法

答案 1 :(得分:-1)

您可以通过nsynjs同步运行代码。您的代码可能会像这样转换:

步骤1.将带有回调的慢速函数包装到nsynjs-aware包装器中:

// content of wrappers.js
user = require("./user");
exports.user_check_user_existence_wrapper = function (ctx, uid) {
    var res = {};

    user.check_user_existence(tid,function(re){
        res.re = re;
        ctx.resume();
    })

    return res;
};
exports.user_check_user_existence_wrapper.nsynjsHasCallback = true;

exports.user_complete_user_existence_wrapper = function(ctx, re, userData) {
    var res = {};

    user.complete_user_existence(tid,function(error,ue_response){
        res.error = error;
        res.ue_response = ue_response;
        ctx.resume(error); // if error is set, it will cause exception in the caller
    })

    return res;
};
exports.user_complete_user_existence_wrapper.nsynjsHasCallback = true;

步骤2.将同步逻辑置于函数中,使用上面的包装器执行慢速函数:

var synchronousCode = function(wrappers,msg) {
    console.log(msg.from);
    var userData = msg.from;
    var tid = userData.id;
    //Check if user is in cache 
    var re = wrappers.user_check_user_existence_wrapper(nsynjsCtx,tid).re;
    if(re < 2)
        try {
            var res = wrappers.user_complete_user_existence_wrapper(re,userData).ue_response;
            console.log('ha');
            play = 1;
        }
        catch (e) {
            bot.api.sendMessage(tid,"Sorry an unexpected error occured!",e);
        };
}

步骤3.通过nsynjs运行同步功能:

var nsynjs = require('nsynjs');
var wrappers = require('./wrappers');
var synchronousCode = function(wrappers,msg) {
....
}

bot.api.on('message', function(msg) {
    nsynjs.run(synchronousCode,{},wrappers,msg,function(){
        console.log('synchronousCode finished');
    })
});

请在此处查看更多示例:https://github.com/amaksr/nsynjs/tree/master/examples/node-module-loading