Есть ли асинхронная блокировка программным языком?
- Синхронизировать путь
Например, рубин:
con = Mysql.new('localhost')
rs1 = con.query('select * from test01') # A
rs2 = con.query('select * from test02') # B
rs = getResult(rs1, rs2) # C
con.close
так A
заблокирует выполнение. B
будет выполняться до A
готово. Так же C
- Асинхронный способ
например, nodejs
var mysql = require('mysql');
var connection = mysql.createConnection({host : 'localhost',});
connection.connect();
connection.query('SELECT * from test01', function(err, rows, fields) {
console.log(rows);
}); // A
connection.query('SELECT * from test02', function(err, rows, fields) {
console.log(rows);
}); // B
connection.end();
A
не будет блокировать B
, но обычно код должен выглядеть так:
connection.query('SELECT * from test01', function(err, rows1, fields) { // A
connection.query('SELECT * from test02', function(err, rows2, fields) { // B
getResult(rows1, rows2); // C
});
});
Или используя обещание выполнить параллельно
Promise.all([
connection.query('SELECT * from test01'),
connection.query('SELECT * from test02'),])
.then(function(data) {
getResult(data[0], data[1])
})
У меня вопрос, так ли это должно быть? Возможно ли это, написав код синхронизации, но получить эффект асинхронности?
Например, languageX:
VAR con = Mysql=>new('localhost') # A
VAR rs1 = con=>query('select * from test01') # B
VAR rs2 = con=>query('select * from test02') # C
VAR rs = getResult(rs1, rs2) # D
con=>close # E
Процесс это:
- A, просто выполните его и отправьте B
- B, выполнить его и переслать на C, и пометить где-нибудь внутри, так как это IO-блокировка
- C, выполнить его и переслать на D, и пометить где-нибудь внутри, так как это IO-блокировка
- D, выполнять его только тогда, когда RS1 и RS2 готовы, но не блокировать здесь, а также не выполнять E(Может обрабатывать другие запросы и т. Д.)
- когда rs1 и rs2 готовы, выполнить и переслать на E
То, что я пытаюсь здесь сказать, это то, что без беспорядка обратного вызова, но с простым, простым и понятным кодом, мы можем получить неблокирующий ввод-вывод.
1 ответ
У меня вопрос, так ли это должно быть? Возможно ли это, написав код синхронизации, но получить эффект асинхронности?
Да. Вы можете использовать async/await на Node 7+ или сопрограммы на основе генератора в более старых версиях Node.
Это будет выглядеть примерно так:
var x = await f1();
var y = await f2(x);
// ...
или даже:
var y = await f2(await f1());
// ...
но он все равно будет асинхронным и неблокирующим. Вы можете использовать этот синтаксис с любой функцией, которая возвращает обещание - как это делают многие драйверы баз данных и ORM /ODM в Node.
Посмотрите эти ответы для большего количества примеров: