Я пишу свое первое приложение в 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();
}
Вы можете использовать обратные вызовы или обещания
Вы можете использовать асинхронный модуль или мьютексы
Если вам нужно сериализовать некоторые асинхронные функции, вы можете использовать один из следующих подходов:
Callback и Promise в основном используются для связанных функций, для которых вторая функция нуждается в первой функции .bluebird — это модуль для создания обещаний и полной их настройки.
Асинхронный модуль — это хороший способ асинхронного запуска функций и получения их результатов.
Последний способ — это Mutex, если у вас была асинхронная запись в один объект или файл, вам нужен подход с блокировкой-разблокировкой
Вы можете запустить код синхронно через 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