多种不同结果的返回模式

探讨个问题哈,我现在再做一个 HTML 校验工具,先将 HMTL 源码解析成 DOM 树, 其间可能遇到语法错误,为了发现更多的错误,会跳到下一个分界点继续解析; 然后将解析得到的 DOM 树返回给 lint 工具继续进行进一步的语法、语义解析。 其过程是:

1var dom = parse(html){cap(err); return dom;};
2var lintErr = lint(dom){return err;};

最终需要将 parse 和 lint 的错误收集到一起反馈给服务端。

请问,parse 有什么好的方式来返回解析时错误信息?

之前先是将 parse 设计成了函数式,但是我觉得下面这种返回方式很不好:

1return {
2    dom: dom,
3    err: err
4};

另外一种思路

HTMLParser 设计成独立的类(而不是上面的函数方式)

1var HTMLParser = function(){
2    var err = [];
3    this.parse = function(html){
4        var dom = {};
5
6        err.push(new Error("this is not error."));
7        err.push(new Error("err is not error."));
8
9        return dom;
10    };
11    this.getErrors = function(){
12        return err;
13    };
14};
15
16function main(html){
17    var parser = new HTMLParser();
18    var dom = parser.parse(html);
19    var err = parser.getErrors();
20    var result = HTMLint(dom);
21
22    // concat array to err.
23    Array.prototype.push.apply(err, result);
24
25    return err;
26};

貌似这种方式比上面的稍好一点,不过我又不想为此将原本很简单的函数式改成 对象式。

外部数据存储

1var Console = (function(){
2    var _err = [];
3    function log(err){
4        _err.push(err);
5    }
6    function getErr(){
7        return _err;
8    }
9
10    return {
11        log: log,
12        getErrors: getErr
13    };
14});
15var HTMLParse = function(){
16    Console.log(new Error("syntax error."));
17    Console.log(new Error("parse error"));
18
19    return dom;
20};
21var HTMLint = function(dom){
22    var err = [];
23    err.push(new Error("lint error."));
24    err.push(new Error("lint error."));
25    return err;
26};
27function main(html){
28    var dom = HTMLParse(html);
29    var parseErr = Console.getErrors();
30    var lintErr = HTMLint(dom);
31
32    Array.prototype.push.apply(parseErr, lintErr);
33
34    return parseErr;
35}

对于只有一个实例(或运行一次)的情况,第三方独立的 console 是合适的。 但是一旦需要多个实例(或运行多次,每次Parse的结果都各自独立, 每个html的parse和lint的错误结果各自拼接一起,但是不是所有的html的parse+lint错误结果拼接在一起) 的情况,还是将解析异常信息和解析器本身绑定在一起(比如类)的方式比较合适。

上面的文字有点绕,表达式:

err0 = parseError0 + lintError0; err1 = parseError1 + lintError1;

err0 和 err1 是各自独立的,实例化多个第三方独立的有专用的Console,不如用类的方式好了。

寻求指教

对于这种需要返回多种不同数据的函数式, 如果你有其他的方案,欢迎回帖、回邮,或回博交流指导 :)

更新 (2013)

事件机制可能是最好的选择:

1parser.on("error", function(err){
2});

Tags: 设计模式

Published on 2011-06-08