在 Web Worker 中发出 HTTP 请求

And*_*ann 5 javascript concurrency multithreading web-worker node.js

我第一次尝试在我的节点应用程序中使用网络工作者或线程。我正在使用webworker-threads npm 模块

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

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

由于这是第一次在节点中使用网络工作线程/线程,我可能会误解如何使用这些东西。这是我尝试过的一个例子:

服务器.js

var Worker = require('webworker-threads').Worker;
var worker = new Worker('worker.js');
Run Code Online (Sandbox Code Playgroud)

工人.js

console.log("before import");
importScripts('./node_modules/request/request.js');
console.log("after import");
Run Code Online (Sandbox Code Playgroud)

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

bar*_*zag 6

Web Worker 仅是本机 JavaScript,因此您无法使用它们实现您想要的功能。工作线程不支持node.js api 或npm 包(如http 或request.js)。对于并发性,您不需要任何多线程魔法,只需使用 async.js 或 Promise。如果您想使用线程,那么 child_processes 就是您的最佳选择。您还可以使用 API 来管理 child_processes,例如https://github.com/rvagg/node-worker-farm

考虑到你的例子,你可以写这样的东西:

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);
    });
});
Run Code Online (Sandbox Code Playgroud)

孩子.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);
    });
};
Run Code Online (Sandbox Code Playgroud)