Linux中JS如何实现并发控制
导读:在Linux环境下,使用JavaScript进行并发控制可以通过多种方式实现,具体取决于你所使用的JavaScript运行环境(如Node.js或浏览器)。以下是几种常见的方法: 1. 使用 async/await 和 Promise.al...
在Linux环境下,使用JavaScript进行并发控制可以通过多种方式实现,具体取决于你所使用的JavaScript运行环境(如Node.js或浏览器)。以下是几种常见的方法:
1. 使用 async/await 和 Promise.all
这是最常用的并发控制方法之一,适用于Node.js和现代浏览器。通过将异步操作封装在Promise中,并使用Promise.all来并行执行多个任务,同时控制并发数量。
示例代码(限制并发数为5):
const async = require('async');
// 模拟异步任务
function asyncTask(item) {
return new Promise((resolve) =>
{
setTimeout(() =>
{
console.log(`任务完成: ${
item}
`);
resolve(item);
}
, 1000);
}
);
}
// 控制并发数的函数
async function runTasks(tasks, concurrency) {
const results = [];
const executing = [];
for (const task of tasks) {
const p = asyncTask(task).then(result =>
{
results.push(result);
executing.splice(executing.indexOf(p), 1);
}
);
results.push(p);
executing.push(p);
if (executing.length >
= concurrency) {
await Promise.race(executing);
}
}
await Promise.all(executing);
return results;
}
// 使用示例
const tasks = Array.from({
length: 20 }
, (_, i) =>
`任务${
i + 1}
`);
runTasks(tasks, 5).then(results =>
{
console.log('所有任务完成:', results);
}
);
使用第三方库 p-limit
p-limit 是一个轻量级的库,用于限制并发Promise的数量。
安装:
npm install p-limit
示例代码:
const pLimit = require('p-limit');
// 模拟异步任务
function asyncTask(item) {
return new Promise((resolve) =>
{
setTimeout(() =>
{
console.log(`任务完成: ${
item}
`);
resolve(item);
}
, 1000);
}
);
}
const limit = pLimit(5);
// 限制并发数为5
const tasks = Array.from({
length: 20 }
, (_, i) =>
`任务${
i + 1}
`);
const promises = tasks.map(task =>
limit(() =>
asyncTask(task)));
Promise.all(promises).then(results =>
{
console.log('所有任务完成:', results);
}
);
2. 使用生成器(Generators)和 co 库
生成器函数可以与co库结合使用,以实现更简洁的并发控制。
安装 co:
npm install co
示例代码:
const co = require('co');
// 模拟异步任务
function asyncTask(item) {
return new Promise((resolve) =>
{
setTimeout(() =>
{
console.log(`任务完成: ${
item}
`);
resolve(item);
}
, 1000);
}
);
}
// 控制并发数的生成器函数
function* runTasks(tasks, concurrency) {
const results = [];
const queue = tasks.slice();
while (queue.length >
0) {
const workers = Array.from({
length: concurrency }
, () =>
queue.shift());
const done = yield Promise.all(workers.map(task =>
asyncTask(task)));
results.push(...done);
}
return results;
}
co(runTasks.bind(null, Array.from({
length: 20 }
, (_, i) =>
`任务${
i + 1}
`), 5)).then(results =>
{
console.log('所有任务完成:', results);
}
);
3. 使用线程池(适用于Node.js)
Node.js原生不支持多线程,但可以使用第三方库如worker_threads来创建线程池,实现并发控制。
示例代码:
const {
Worker, isMainThread, parentPort }
= require('worker_threads');
if (isMainThread) {
const numTasks = 20;
const concurrency = 5;
const tasks = Array.from({
length: numTasks }
, (_, i) =>
`任务${
i + 1}
`);
const workers = [];
let completed = 0;
const results = [];
function runWorker() {
if (tasks.length === 0) {
console.log('所有任务完成:', results);
process.exit(0);
return;
}
const task = tasks.shift();
const worker = new Worker(__filename);
worker.postMessage(task);
workers.push(worker);
worker.on('message', (result) =>
{
results.push(result);
completed++;
workers.splice(workers.indexOf(worker), 1);
runWorker();
}
);
worker.on('error', (err) =>
{
console.error(err);
workers.splice(workers.indexOf(worker), 1);
runWorker();
}
);
worker.on('exit', (code) =>
{
if (code !== 0)
console.error(`Worker stopped with exit code ${
code}
`);
workers.splice(workers.indexOf(worker), 1);
runWorker();
}
);
}
runWorker();
}
else {
parentPort.on('message', async (task) =>
{
// 模拟异步任务
await new Promise(resolve =>
setTimeout(resolve, 1000));
parentPort.postMessage(`完成: ${
task}
`);
}
);
}
4. 使用事件驱动的方法
在Node.js中,可以利用事件循环和事件驱动的特性,通过自定义事件来管理并发任务。
示例代码:
const EventEmitter = require('events');
class TaskManager extends EventEmitter {
constructor(concurrency) {
super();
this.concurrency = concurrency;
this.running = 0;
this.queue = [];
}
addTask(task) {
this.queue.push(task);
this.next();
}
next() {
while (this.running <
this.concurrency &
&
this.queue.length >
0) {
const task = this.queue.shift();
this.running++;
task().then(result =>
{
this.emit('taskDone', result);
}
).catch(err =>
{
this.emit('taskError', err);
}
).finally(() =>
{
this.running--;
this.next();
}
);
}
}
}
// 使用示例
const taskManager = new TaskManager(5);
const tasks = Array.from({
length: 20 }
, (_, i) =>
() =>
new Promise((resolve) =>
{
setTimeout(() =>
{
console.log(`任务完成: ${
i + 1}
`);
resolve(`结果${
i + 1}
`);
}
, 1000);
}
)
);
tasks.forEach(task =>
taskManager.addTask(task));
taskManager.on('taskDone', result =>
{
console.log('任务结果:', result);
}
);
taskManager.on('taskError', err =>
{
console.error('任务出错:', err);
}
);
总结
在Linux环境下使用JavaScript进行并发控制,主要依赖于Promise、async/await以及第三方库如p-limit等工具。选择具体的方法应根据项目需求、运行环境以及个人偏好来决定。对于Node.js,还可以利用多线程或事件驱动的方法来实现更复杂的并发控制。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Linux中JS如何实现并发控制
本文地址: https://pptw.com/jishu/742363.html
