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

  • Способ синхронизации

Например, ruby:

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])
 })

Мой вопрос в том, должен ли он быть таким? Можно ли написать код синхронизации, но получить асинхронный эффект?

Например, языкX:

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

Что я пытаюсь сказать здесь, без беспорядка обратного вызова, но чистого, простого, простого кода мы можем получить неблокирующий IO.

Ответ 1

Мой вопрос в том, должен ли он быть таким? Можно ли написать код синхронизации, но получить асинхронный эффект?

Да. Вы можете использовать async/await в Node 7+ или на основе генератора на старых версиях Node.

Он будет выглядеть примерно так:

var x = await f1();
var y = await f2(x);
// ...

или даже:

var y = await f2(await f1());
// ...

но он все равно будет асинхронным и неблокирующим. Вы можете использовать этот синтаксис с любой функцией, которая возвращает обещание - как это делают многие драйверы базы данных и ORM/ODM в Node.

См. ответы на следующие примеры: