如何在Javascript中编写非阻塞回调?

时间:2015-03-25 03:13:01

标签: javascript node.js

以下是我正在尝试的一些代码:

startTask();

function startTask(){
    console.log('startTask enter');
    startLongTask(1, function(){
        console.log('long task complete');
    });
    console.log('startTask exit');
}

function startLongTask(i, callback) {
    while (i++ < 10000){
        console.log(i);
    }
    callback();
}

这是输出(省略数字上的大系列):

startTask enter
2
3
4
5
6
7
8
9
10
long task complete
startTask exit

很明显,如果我有一个长时间运行的操作,它是同步的。它就像在 startTask 中内联 startLongTask 一样。如何修复此回调为非阻塞。我期望的输出是:

startTask enter
startTask exit
2
3
4
5
6
7
8
9
10
long task complete

2 个答案:

答案 0 :(得分:1)

仅Javascript代码无法在纯JS中创建新的异步操作,因为node.js中的V8解释器不能为您提供完整的线程。

诸如node.js中的fs模块之类的库从本机操作(在JS / V8世界之外)获得它们的异步行为,并且它们通过异步接口与JS引擎连接。

也就是说,有些方法可以通过使用一些非JS代码在node.js中在后台运行操作。你可以启动另一个进程,你可以使用各种支持其他执行线程的附加模块......所有这些都将超出纯node.js Javascript以提供异步接口。

如果您的任务可以分成短块,您还可以通过对连续计时器进行少量工作来模拟异步操作(这也是浏览器中常见的解决方法)。

答案 1 :(得分:0)

您可以使用延迟为0毫秒的超时功能。超时中的任何函数都将被推送到执行线程的末尾。 e.g。

startTask();

function startTask(){
    console.log('startTask enter');
    setTimeout(function(){
        startLongTask(1, function(){
            console.log('long task complete');
        })
    }, 0);
    console.log('startTask exit');
}

function startLongTask(i, callback) {
    while (i++ < 100){
        console.log(i);
    }
    callback();
}