Есть ли асинхронная блокировка программным языком?

  1. Синхронизировать путь

Например, рубин:

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

  1. Асинхронный способ

например, 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

Процесс это:

  1. A, просто выполните его и отправьте B
  2. B, выполнить его и переслать на C, и пометить где-нибудь внутри, так как это IO-блокировка
  3. C, выполнить его и переслать на D, и пометить где-нибудь внутри, так как это IO-блокировка
  4. D, выполнять его только тогда, когда RS1 и RS2 готовы, но не блокировать здесь, а также не выполнять E(Может обрабатывать другие запросы и т. Д.)
  5. когда 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.

Посмотрите эти ответы для большего количества примеров:

Другие вопросы по тегам