- Sync way
例如,红宝石:
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
会阻塞执行。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并行执行
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。