【爪哇脚本正义之一】 不要抱着金饭碗要饭

许多爪哇脚本程序员每每在抱怨所谓的 回调陷阱 , 岂不知随时随地的创建回调恰恰是异步编程 最爽的地方。当然,由于很多人在能够真正驾驭它之前就已经投降了,并不能体会到爪哇脚本真正的魅力。 反而该去努力引入各种顺序编程的各种概念,终于成功推出了一个不伦不类的ES6。

不要再抱着金饭碗要饭了!

认识爪哇脚本,从下面的例子开始 。。。

如果你看不懂第51行的代码是什么意思,下面的内容可以不用看了,你需要继续学习什么是爪哇脚本。

下面的例子是一个经典并发请求的例子。用爪哇脚本最基本的功能来实现,代码结构清晰,优雅,控制可以非常灵活。 在这个基础上可以扩展到很多其他的应用场合。

下面这段代码的关键在第32行

第10-18行定义了一个适合并行请求的数据结构,里面包含了所有的请求和请求的状态,这个结构可以根据实际需要调整。

第22-23行同时发出了所有的url请求

第32行将每一个请求绑定到这个请求所对应的数据结构上,这样在回调函数对象内部的 this 指针就会指向这个数据结构。 再通过第13行定义的 targets 对象可以访问到最外部的对象实例。

每一个请求收到返回结果之后设置自己的完成标志,并调用上层对象的结束函数

第37-41行检查是否所有的请求都已经完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var request = require('request');

var urls = [
'http://www.baidu.com',
'http://www.github.com'
];

function Request_all(urls) {
console.log("urls = ", urls);
this.targets = [];
urls.forEach(function (url) {
this.targets.push({
targets : this,
url : url,
finished : false,
result : {}
});
}.bind(this));
this.go();
};
Request_all.prototype.go = function () {
this.targets.forEach(function (target) {
request(target.url, function (error, response, body) {
this.result = {
err : error,
res : response,
body : body
}
this.finished = true;
console.log(target.url, "done", response.statusCode);
this.targets.done();
}.bind(target));
}.bind(this));
};
Request_all.prototype.done = function () {
var finished = true;
this.targets.forEach(function (target) {
if (!target.finished) {
finished = false;
}
});
if (finished) {
console.log("====== final result =====");
this.targets.forEach(function (target) {
console.log(target.url, target.result.res.statusCode);
});
}

};

new Request_all(urls);