Do async in a blocking program language way?

帅比萌擦擦* 提交于 2019-12-31 05:39:26

问题


  1. Sync way

For example, 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  

so A will block the execution. B will be executed until A is done. So does C

  1. Async way

for example, 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 will not block B, but normally the code should look like this:

connection.query('SELECT * from test01', function(err, rows1, fields) {   // A
  connection.query('SELECT * from test02', function(err, rows2, fields) { // B
    getResult(rows1, rows2); // C
  });
});

Or Using promise to execute in parallelly

Promise.all([
connection.query('SELECT * from test01'),
connection.query('SELECT * from test02'),])
.then(function(data) {
  getResult(data[0], data[1])
 })

My question is, does it have to be in this way? Is it possible by writing sync code but get a async effect?

For example, 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

process is:

  1. A, just execute it and forward to B
  2. B, execute it and forward to C, and mark somewhere internally as this is IO-blocking
  3. C, execute it and forward to D, and mark somewhere internally as this is IO-blocking
  4. D, execute it only when rs1 and rs2 are ready, but not block here, also not execute E(Can handle other requests, etc)
  5. when rs1 and rs2 are ready, execute and forward to E

What am I trying to say here is, without the mess of callback but clean, simply, plain code we can get non-blocking IO.


回答1:


My question is, does it have to be in this way? Is it possible by writing sync code but get a async effect?

Yes. You can use async/await on Node 7+ or generator based coroutines on older versions of Node.

It will look something like:

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

or even:

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

but it will still be asynchronous and non-blocking. You can use that syntax with any function that returns a promise - like a lot of the database drivers and ORMs/ODMs in Node do.

See those answers for more examples:

  • How do I send multiple queries from one endpoint with Express?
  • I can't get the value of "result" in Node.js


来源:https://stackoverflow.com/questions/43973850/do-async-in-a-blocking-program-language-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!