如何在Express请求处理程序中编写非阻塞异步函数 [英] How to write non-blocking async function in Express request handler

查看:52
本文介绍了如何在Express请求处理程序中编写非阻塞异步函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部:

我对Node异步编程还很陌生,我想知道如何编写一些Express请求处理程序,该处理程序可以处理耗时的繁重计算任务,而不会在请求之后阻塞Express处理?

I am pretty new to Node async programming, I wonder how can I write some Express request handler which can handle time consuming heavy calculation task without block Express handling following request?

我认为setTimeout可以做到这一点,以将工作置于事件循环中,但它仍会阻止其他请求:

I thought setTimeout can do that to put the job in a event loop, but it still block other requests:

var express = require('express');
var router = express.Router();


function heavy(callback){
    setTimeout(callback, 1);
}

router.get('/', function(req, res, next) {
    var callback = function(req, res){
        var loop = +req.query.loop;
        for(var i=0; i<loop; i++){
            for(var j=0; j<loop; j++){}
        }
        res.send("finished task: "+Date.now());
    }.bind(null, req, res);

    heavy(callback)
}); 

我想我不了解setTimeout的工作原理(我对setTimeout的了解是在延迟1ms之后,它将在单独的线程/进程中触发回调,而不会阻塞其他繁重的调用),任何人都可以告诉我该怎么做这不会阻止其他对heavy()的请求吗?

I guess I did not understand how setTimeout works(my understanding about setTimeout is after that 1ms delay it will fire up the callback in a seperated thread/process without blocking other call of heavy), could any one show me how to do this without blocking other request to heavy()?

谢谢

推荐答案

最好使用process.nextTick或setImmediate(取决于od,当您希望运行回调时),而不是setTimeout.但是将长时间运行的代码放入函数中是不够的,因为它仍然会在短短一毫秒后阻塞您的线程.

Instead of setTimeout it's better to use process.nextTick or setImmediate (depending od when you want your callback to be run). But it is not enough to put a long running code into a function because it will still block your thread, just a millisecond later.

您需要破坏代码并多次运行setImmediate或process.nextTick-就像在每次迭代中一样,然后从中计划一个新的迭代.否则您将一无所获.

You need to break your code and run setImmediate or process.nextTick multiple times - like in every iteration and then schedule a new iteration from that. Otherwise you will not gain anything.

代替这样的代码:

var a = 0, b = 10000000;

function numbers() {
  while (a < b) {
    console.log("Number " + a++);
  }
}

numbers();

您可以使用如下代码:

var a = 0, b = 10000000;

function numbers() {
  var i = 0;
  while (a < b && i++ < 100) {
    console.log("Number " + a++);
  }
  if (a < b) setImmediate(numbers);
}

numbers();

第一个将阻塞您的线程(并可能使您的调用堆栈溢出),第二个不会阻塞(或者,更准确地说,它将在很短的时间内将您的线程阻塞10000000次,让其他内容在其中运行在那一刻之间.

The first one will block your thread (and likely overflow your call stack) and the second one will not block (or, more precisely, it will block your thread 10000000 times for a very brief moment, letting other stuff to run in between those moments).

您还可以考虑在C/C ++中生成外部进程或编写本机加载项,以便在其中使用线程.

You can also consider spawning an external process or writing a native add on in C/C++ where you can use threads.

有关更多信息,请参见:

For more info see:

这篇关于如何在Express请求处理程序中编写非阻塞异步函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆