你怎么写非阻塞模块?

时间:2013-07-24 19:32:57

标签: javascript node.js io nonblocking

来自完全不同的背景,Node.js的工作方式对我来说仍然是一个非常陌生的概念。我正在掌握在函数中使用回调的概念,但是当我试图支持模块化开发并因此更好地扩展时,我很难将其付诸实践。

例如,如何将函数的结果返回给我的代码,或者更确切地说,不阻塞地访问?我一直在阅读它,但我无法理解这是如何完成的,因为每个人都给了我一个不同的答案。记录日志功能,例如:

exports.log = function (req, res, type) {
    // do stuff here
}

提前致谢。

1 个答案:

答案 0 :(得分:3)

function doStuff (someValue, someOtherValue, someCallBack) {
    console.log("First Value: " + someValue);

    while(someValue-- != 0) {console.log(someValue);}
    someCallBack(someOtherValue);
}

function delayEventLoopMore(someValue) {

    while(someValue-- != 0) {console.log('The value:' + someValue);}
}

doStuff(100000, 100000, delayEventLoopMore);

console.log('YAY!');

前面的代码是阻止涉及回调的代码的示例。显然,简单地提供回调参数并没有使这段代码无阻塞。如果你运行它,你应该清楚地看到两个不同的计数从100,000到0,然后最后打印'YAY'。如果这个功能没有阻塞,我们肯定有足够的时间打印'Yay'。如果您怀疑这种情况可以将价值增加到数百万甚至数十亿。 “耶”将永远是印刷的最后一件事。

真正的异步,非阻塞行为来自V8后端。复制它的唯一方法是生成本机扩展。

以下是此功能的两个版本:

exports.log = function (someFileName) {
    var results;

    results = fs.readFileSync(someFileName);

    return results;
}


exports.log = function (someFileName, callback) {
    var results;


    fs.readFile(someFileName, function(data) {
        results = data;//unnecessary just for clarity!
        callback(results);
    }
}

第一个版本假设您正在执行的任何操作都是同步的。在这种情况下使用回调绝对没有任何好处。只需返回结果。无论哪种方式,它都会在事件循环中产生完全相同的延迟量。如果你在这里做的工作非常耗费CPU,你可能会坚持这一点。

如果是I / O密集型,您可以执行以下两项操作之一。答:利用已经开发的Async节点模块:http,fs,有一些好的mongodb等等......或者如果你的用例没有任何存在,为它开发一个原生扩展。无论如何,您返回结果的方式是通过用户提供给您的回调,并使用您在异步操作过程中构建的“结果”的内容来调用此回调。