autobahn JS, что если вызываемый RPC является асинхронным?
В документации autobahnJS представлен следующий пример, иллюстрирующий настройку удаленного вызова процедуры (RPC):
...
// 3) register a procedure for remoting
function add2(args) {
return args[0] + args[1];
}
session.register('com.myapp.add2', add2);
// 4) call a remote procedure
session.call('com.myapp.add2', [2, 3]).then(
function (res) {
console.log("Result:", res);
}
);
...
Что если add2 необходимо выполнить асинхронную операцию? Моя идея заключалась в том, что, возможно, можно было бы перезвонить другой удаленной функции, зарегистрированной в клиенте, которая инициировала первоначальный вызов backend.add2. Что-то вроде этого:
...
//backend code
function add2(args) {
setTimeout(function() {
console.log("We are done here");
session.call('client.added', [123])
}, 1000);
return null; // useless, this value is never used
}
session.register('backend.add2', add2);
// client code
session.call('backend.add2', [2, 3]).then(
function (res) {
console.log("Result:", res);
}
);
...
Видите ли вы лучший вариант? Это кажется немного громоздким для меня. В идеале add2 вернул бы обещание. Но я не уверен, возможно ли это через RPC?
2 ответа
Решение
Вы можете вернуть обещание, которое затем разрешается после возврата асинхронной функции.
Со справочной страницы API AutobahnJS:
function myAsyncFunction(args, kwargs, details) {
var d = new autobahn.when.defer();
setTimeout(function() {
d.resolve("async finished");
}, 1000);
return d.promise;
}
Мой пример регистрации асинхронной функции
session.register('com.forlunch.list_chats', function (args, kwargs, details) {
return functions.list_chats(args);
})
которые делают запрос к базе данных MySQL
async function list_chats(params){
var query = "SELECT * WHERE ... ;"
let res = await mysql_query(query)
return res
}
function mysql_query (query){
return new Promise(function(resolve, reject) {
const con = mysql.createConnection(mysql_options);
con.query(query,[], function (err, rows, fields) {
if (err) return reject(err);
resolve(rows);
});
})
}