在Web Worker中发出HTTP请求

时间:2015-05-22 02:31:01

标签: javascript node.js multithreading concurrency web-worker

我第一次尝试在节点应用程序中使用Web工作者或线程。我使用的是webworker-threads npm module

基本上我希望每个工作者向服务器发出请求,测量响应时间并将其发送回主线程。

我尝试了很多不同的方法,但我似乎无法让它发挥作用。文档的基本示例有效。但是当我尝试要求一个模块(在我的情况下是“请求”)时,工作人员似乎停止工作,没有任何错误消息。我在文档中看到需要在worker中不起作用,所以我尝试了“importScripts()”,这也不起作用。当我使用线程池时,我尝试使用.all.eval(),但它也没有用。

由于这是第一次使用节点中的web-workers / threads,我可能会误解如何使用这些东西。这是我尝试过的一个例子:

server.js

var Worker = require('webworker-threads').Worker;
var worker = new Worker('worker.js');

worker.js

console.log("before import");
importScripts('./node_modules/request/request.js');
console.log("after import");

此基本示例仅打印before import然后停止。

1 个答案:

答案 0 :(得分:3)

Web workers are native javascript only so you can't achieve what you want with them. Worker threads don't support node.js api or npm packages(like http or request.js). For concurrency you don't need any multithread magic just use async.js or promises. If you want to play with threads then child_processes is the way to go. You could also use an API to manage child_processes like https://github.com/rvagg/node-worker-farm

Considering your example you could write something like this:

main.js

var workerFarm = require('worker-farm')
, workers    = workerFarm(require.resolve('./child'))
, ret        = 0;

var urls = ['https://www.google.com', 'http://stackoverflow.com/', 'https://github.com/']; 

urls.forEach(function (url) {
    workers(url, function (err, res, body, responseTime) {
        console.log('Url ' + url + 'finished in ' + responseTime + 'ms');    
        //Ugly code here use async/promise instead
        if (++ret == urls.length)
            workerFarm.end(workers);
    });
});

child.js

var request = require('request');

module.exports = function(url, cb) {
    var start = new Date();
    request(url, function(err, res, body) {
        var responseTime = new Date() - start;
        cb(err, res, body, responseTime);
    });
};