问题
- 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
- 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:
- A, just execute it and forward to B
 - B, execute it and forward to C, and mark somewhere internally as this is IO-blocking
 - C, execute it and forward to D, and mark somewhere internally as this is IO-blocking
 - D, execute it only when rs1 and rs2 are ready, but not block here, also not execute E(Can handle other requests, etc)
 - 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