如何在 NodeJS 中控制应用程序的流动
Posted
技术标签:
【中文标题】如何在 NodeJS 中控制应用程序的流动【英文标题】:How to control the flow of applications in NodeJS 【发布时间】:2017-10-30 00:29:08 【问题描述】:我正在用 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();
【问题讨论】:
您可能想看看如何在 node.js(或一般的 javascript)中使用 async/await 和 promises。这里稍微介绍一下:blog.readme.io/using-async-await-in-node-js-7-6-0 很棒的线路,I come from a php background where everything was simple, procedural, one after the other.
喜欢它。
【参考方案1】:
您可以使用回调或承诺 您可以使用异步模块或互斥锁
如果您需要序列化一些异步函数,您可以使用以下方法之一:
Callback
Native promises
Bluebird promise
Async module
Callback 和 Promise 主要用于相关函数,第二个函数需要第一个函数。bluebird 是一个用于创建 Promise 并对其进行完全自定义的模块。
异步模块是异步运行函数并一起获取结果的好方法。
如果您在单个对象或文件中进行异步写入,则最后一种方法是 Mutex,您需要锁定释放方法
【讨论】:
【参考方案2】:您可以通过nsynjs 同步运行代码。您的代码可能会像这样转换:
步骤 1. 将带有回调的慢速函数包装到支持 nsynjs 的包装器中:
// 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
【讨论】:
以上是关于如何在 NodeJS 中控制应用程序的流动的主要内容,如果未能解决你的问题,请参考以下文章
对于Passenger,控制台日志(从puts的输出)去哪里......对于Nodejs