搜索
首页web前端js教程详解从Node.js的child_process模块来学习父子进程之间的通信的示例代码

这篇文章主要介绍了从Node.js的child_process模块来学习父子进程之间的通信,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

child_process模块提供了和popen(3)一样的方式来产生自进程,这个功能主要是通过child_process.spawn函数来提供的:

const spawn = require('child_process').spawn; 
const ls = spawn('ls', ['-lh', '/usr']); 
ls.stdout.on('data', (data) => { 
 console.log(`stdout: ${data}`); 
}); 
ls.stderr.on('data', (data) => { 
 console.log(`stderr: ${data}`); 
}); 
ls.on('close', (code) => { 
 console.log(`child process exited with code $[code]`); 
});

默认情况下,Node.js进程和子进程之间的stdin,stdout,stderr管道是已经存在的。通常情况下这个方法可以以一种非阻塞的方式来传递数据。(注意,有些程序在内部使用line-buffered I/O。因为这也不会影响到Node.js,这意味着传递给子进程的数据可能不会马上消费)。

chid-process的spawn方法是通过一种异步的方式来产生自进程的,因此不会阻塞Node.js的事件循环,然而child-process.spawnSync方法是同步的,他会阻塞事件循环只到产生的进程退出或者终止。

child_process.exec:产生一个shell客户端,然后使用shell来执行程序,当完成的时候传递给回调函数一个stdout和stderr

child_process.execFile:和exec相似,但是他不会马上产生一个shell

child_process.fork:产生一个新的Node.js进程,同时执行一个特定的模块来产生IPC通道,进而在父进程和子进程之间传输数据

child_process.execSync:和exec不同之处在于会阻塞Node.js的事件循环,然而child-process

child_process.execFileSync:和execFile不同之处在于会阻塞Node.js的事件循环,然而child-process在一些特殊情况下,例如自动化shell脚本,同步的方法可能更加有用。多数情况下,同步的方法会对性能产生重要的影响,因为他会阻塞事件循环

child_process.spawn(), child_process.fork(), child_process.exec(), and child_process.execFile()都是异步的API。每一个方法都会产生一个ChildProcess实例,而且这个对象实现了Node.js的EventEmitter这个API,于是父进程可以注册监听函数,在子进程的特定事件触发的时候被调用。 child_process.exec() 和 child_process.execFile()可以指定一个可选的callback函数,这个函数在子进程终止的时候被调用。

在windows平台上执行.bat和.cmd:

child_process.exec和child_process.execFile的不同之处可能随着平台不同而有差异。在Unit/Linux/OSX平台上execFile更加高效,因为他不会产生shell。在windows上,.bat/.cmd在没有终端的情况下是无法执行的,因此就无法使用execFile(child_process.spawn也无法使用)。在window上,.bat/.cmd可以使用spawn方法,同时指定一个shell选项;或者使用child_process.exec或者通过产生一个cmd.exe同时把.bat/.cmd文件传递给它作为参数(child_process.exec就是这么做的)。

const spawn = require('child_process').spawn; 
const bat = spawn('cmd.exe', ['/c', 'my.bat']);//使用shell方法指定一个shell选项 
bat.stdout.on('data', (data) => { 
 console.log(data); 
}); 
bat.stderr.on('data', (data) => { 
 console.log(data); 
}); 
 
bat.on('exit', (code) => { 
 console.log(`Child exited with code $[code]`); 
});

或者也可以使用如下的方式:

const exec = require('child_process').exec;//产生exec,同时传入.bat文件 
exec('my.bat', (err, stdout, stderr) => { 
 if (err) { 
  console.error(err); 
  return; 
 } 
 console.log(stdout); 
});

child_process.exec(command[, options][, callback])

其中options中的maxBuffer参数表示stdout/stderr允许的最大的数据量,如果超过了数据量那么子进程就会被杀死,默认是200*1024比特;killSignal默认是'SIGTERM'。其中回调函数当进程结束时候调用,参数分别为error,stdout,stderr。这个方法返回的是一个ChildProcess对象。

const exec = require('child_process').exec; 
const child = exec('cat *.js bad_file | wc -l', 
 (error, stdout, stderr) => { 
  console.log(`stdout: ${stdout}`); 
  console.log(`stderr: ${stderr}`); 
  if (error !== null) { 
   console.log(`exec error: ${error}`); 
  } 
});

上面的代码产生一个shell,然后使用这个shell执行命令,同时对产生的结果进行缓存。其中回调函数中的error.code属性表示子进程的exit code,error.signal表示结束这个进程的信号,任何非0的代码表示出现了错误。默认的options参数值如下:

{ 
 encoding: 'utf8', 
 timeout: 0, 
 maxBuffer: 200*1024,//stdout和stderr允许的最大的比特数据,超过她子进程就会被杀死 
 killSignal: 'SIGTERM', 
 cwd: null, 
 env: null 
}

如果timeout非0,那么父进程就会发送信号,这个信号通过killSignal指定,默认是"SIGTERM"来终结子进程,如果子进程超过了timeout指定的时间。注意:和POSIX系统上调用exec方法不一样的是,child_process.exec不会替换当前线程,而是使用一个shell去执行命令

child_process.execFile(file[, args][, options][, callback])

其中file表示需要执行的文件。 child_process.execFile()和exec很相似,但是这个方法不会产生一个shell。指定的可执行文件会马上产生一个新的线程,因此其效率比child_process.exec高。

const execFile = require('child_process').execFile; 
const child = execFile('node', ['--version'], (error, stdout, stderr) => { 
 if (error) { 
  throw error; 
 } 
 console.log(stdout); 
});

因为不会产生shell,一些I/O redirection和file globbing这些行为不支持

child_process.fork(modulePath[, args][, options])

其中modulePath表示要在子线程中执行的模块。其中options中的参数silent如果设置为true,那么子进程的stdin, stdout, stderr将会被传递给父进程,如果设置为false那么就会从父进程继承。execArgv默认的值为process.execArgv,execPath表示用于创建子进程的可执行文件。这个fork方法是child_process.spawn的一种特殊用法,用于产生一个Node.js的子进程,和spawn一样返回一个ChildProcess对象。返回的ChildProcess会有一个内置的传输通道用于在子进程和父进程之间传输数据(用ChildProcess的send方法完成)。我们必须注意,产生的Node.js进程和父进程之间是独立的,除了他们之间的IPC传输通道以外。每一个进程有独立的内存,有自己独立的V8引擎。由于产生一个子进程需要其他额外的资源分配,因此产生大量的子进程不被提倡。默认情况下,child_process.fork会使用父进程的process.execPath来产生一个Node.js实例,options中的execPath允许指定一个新的路径。通过指定execPath产生的新的进程和父进程之间通过文件描述符(子进程的环境变量NODE_CHANNEL_FD)来通信。这个文件描述符上的input/output应该是一个JSON对象。和POSIX系统调用fork不一样的是,child_process.fork不会克隆当前的进程

最后,我们来看看子进程和父进程之间是如何通信的:

服务器端的代码:

var http = require('http'); 
var cp = require('child_process'); 
var server = http.createServer(function(req, res) { 
  var child = cp.fork(dirname + '/cal.js'); 
  //每个请求都单独生成一个新的子进程 
  child.on('message', function(m) { 
    res.end(m.result + '\n'); 
  }); 
  //为其指定message事件 
  var input = parseInt(req.url.substring(1)); 
  //和postMessage很类似,不过这里是通过send方法而不是postMessage方法来完成的 
  child.send({input : input}); 
}); 
server.listen(8000);

子进程的代码:

function fib(n) { 
  if (n < 2) { 
    return 1; 
  } else { 
    return fib(n - 2) + fib(n - 1); 
  } 
} 
//接受到send传递过来的参数 
process.on(&#39;message&#39;, function(m) { 
  //console.log(m); 
  //打印{ input: 9 } 
  process.send({result: fib(m.input)}); 
});

child_process.spawn(command[, args][, options])

其中options对象的stdio参数表示子进程的stdio配置;detached表示让子进程在父进程下独立运行,这个行为与平台有关;shell如果设置为true那么就会在shell中执行命令。这个方法通过指定的command来产生一个新的进程,如果第二个参数没有指定args那么默认就是一个空的数组,第三个参数默认是如下对象,这个参数也可以用于指定额外的参数:

{
 cwd: undefined, //产生这个进程的工作目录,默认继承当前的工作目录
 env: process.env//这个参数用于指定对于新的进程可见的环境变量,默认是process.env
}

其中cwd用于指定子进程产生的工作目录,如果没有指定表示的就是当前工作目录。env用于指定新进程的环境变量,默认为process.env。下面的例子展示了使用ls -lh/usr来获取stdout,stderr以及exit code:

const spawn = require(&#39;child_process&#39;).spawn; 
const ls = spawn(&#39;ls&#39;, [&#39;-lh&#39;, &#39;/usr&#39;]); 
ls.stdout.on(&#39;data&#39;, (data) => { 
 console.log(`stdout: ${data}`); 
}); 
ls.stderr.on(&#39;data&#39;, (data) => { 
 console.log(`stderr: ${data}`); 
}); 
ls.on(&#39;close&#39;, (code) => { 
 console.log(`child process exited with code $[code]`); 
});

下面是一个很详细的运行"ps ax|grep ssh"的例子:

const spawn = require(&#39;child_process&#39;).spawn; 
const ps = spawn(&#39;ps&#39;, [&#39;ax&#39;]); 
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]); 
ps.stdout.on(&#39;data&#39;, (data) => { 
 grep.stdin.write(data); 
}); 
ps.stderr.on(&#39;data&#39;, (data) => { 
 console.log(`ps stderr: ${data}`); 
}); 
ps.on(&#39;close&#39;, (code) => { 
 if (code !== 0) { 
  console.log(`ps process exited with code $[code]`); 
 } 
 grep.stdin.end(); 
}); 
grep.stdout.on(&#39;data&#39;, (data) => { 
 console.log(`${data}`); 
}); 
grep.stderr.on(&#39;data&#39;, (data) => { 
 console.log(`grep stderr: ${data}`); 
}); 
grep.on(&#39;close&#39;, (code) => { 
 if (code !== 0) { 
  console.log(`grep process exited with code $[code]`); 
 } 
});

用下面的例子来检查错误的执行程序:

const spawn = require(&#39;child_process&#39;).spawn; 
const child = spawn(&#39;bad_command&#39;); 
child.on(&#39;error&#39;, (err) => { 
 console.log(&#39;Failed to start child process.&#39;); 
});

options.detached:

在windows上,把这个参数设置为true的话,这时候如果父进程退出了那么子进程还会继续运行,而且子进程有自己的console window。如果把子进程设置了这个为true,那么就不能设置为false了。在非window平台上,如果把这个设置为true,子进程就会成为进程组合和session的leader,这时候子进程在父进程退出以后会继续执行,不管子进程是否detached。可以参见setsid(2)。

默认情况下,父进程会等待detached子进程,然后退出。要阻止父进程等待一个指定的子进程可以使用child.unref方法,这个方法会让父进程的事件循环不包括子进程,这时候允许父进程独立退出,除非在父进程和子进程之间有一个IPC通道。下面是一个detach长期运行的进程然后把它的输出导向到一个文件:

const fs = require(&#39;fs&#39;); 
const spawn = require(&#39;child_process&#39;).spawn; 
const out = fs.openSync(&#39;./out.log&#39;, &#39;a&#39;); 
const err = fs.openSync(&#39;./out.log&#39;, &#39;a&#39;); 
const child = spawn(&#39;prg&#39;, [], { 
 detached: true,//依赖于父进程 
 stdio: [ &#39;ignore&#39;, out, err ] 
}); 
child.unref();//允许父进程单独退出,不用等待子进程

当使用了detached选项去产生一个长期执行的进程,这时候如果父进程退出了那么子进程就不会继续执行了,除非指定了一个stdio配置(不和父进程之间有联系)。如果父进程的stdio是继承的,那么子进程依然会和控制终端之间保持关系。

options.stdio

这个选项用于配置父进程和子进程之间的管道。默认情况下,子进程的stdin,stdout,stderr导向了ChildProcess这个对象的child.stdin,child.stdout,child.stderr流,这和设置stdio为['pipe','pipe','pipe']是一样的。stdio可以是下面的任何一个字符串

'pipe':相当于['pipe','pipe','pipe'],为默认选项

'ignore':相当于['ignore','ignore','ignore']

'inherit':相当于[process.stdin,process.stdout,process.stderr]或者[0,1,2]

一般情况下,stdio是一个数组,每一个选项对应于子进程的fd。其中0,1,2分别对应于stdin,stdout,stderr。如果还设置了多于的fds那么就会用于创建父进程和子进程之间的额外的管道,可以是下面的任何一个值:

'pipe':为子进程和父进程之间创建一个管道。父进程管道的末端会作为child_process对象的ChildProcess.stdio[fd]而存在。fds0-2创建的管道在ChildProcess.stdin,ChildProcess.stdout,ChildProcess.stderr也是存在的

'ipc':用于创建IPC通道用于在父进程和子进程之间传输消息或者文件描述符。ChildProcess对象最多有一个IPC stdio文件描述符,使用这个配置可以启用ChildProcess的send方法,如果父进程在文件描述符里面写入了JSON对象,那么ChildProcess.on("message")事件就会在父进程上触发。如果子进程是Node.js进程,那么ipc配置就会启用子进程的process.send(), process.disconnect(), process.on('disconnect'), and process.on('message')方法。

'ignore':让Node.js子进程忽视文件描述符。因为Node.js总是会为子进程开启fds0-2,设置为ignore就会导致Node.js去开启/dev/null,同时把这个值设置到子进程的fd上面。

'strem':和子进程之间共享一个可读或者可写流,比如file,socket,pipe。这个stream的文件描述符和子进程的文件描述符fd是重复的。注意:流必须有自己的文件描述符

正整数:表示父进程的打开的文件描述符。和stream对象可以共享一样,这个文件描述符在父子进程之间也是共享的
null/undefined:使用默认值。stdio的fds0,1,2管道被创建(stdin,stdout,stderr)。对于fd3或者fdn,默认为'ignore'

const spawn = require(&#39;child_process&#39;).spawn; 
// Child will use parent&#39;s stdios 
//使用父进程的stdios 
spawn(&#39;prg&#39;, [], { stdio: &#39;inherit&#39; }); 
//产生一个共享process.stderr的子进程 
// Spawn child sharing only stderr 
spawn(&#39;prg&#39;, [], { stdio: [&#39;pipe&#39;, &#39;pipe&#39;, process.stderr] }); 
// Open an extra fd=4, to interact with programs presenting a 
// startd-style interface. 
spawn(&#39;prg&#39;, [], { stdio: [&#39;pipe&#39;, null, null, null, &#39;pipe&#39;] });

注意:当子进程和父进程之间建立了IPC通道,同时子进程为Node.js进程,这时候开启的具有IPC通道的子进程(使用unref)直到子进程注册了一个disconnect的事件处理句柄process.on('disconnect'),这样就会允许子进程正常退出而不会由于IPC通道的打开而持续运行。

Class: ChildProcess

这个类的实例是一个EventEmitters,用于代表产生的子进程。这个类的实例不能直接创建,必须使用 child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork()来完成

'close'事件:

其中code表示子进程退出的时候的退出码;signal表示终止子进程发出的信号;这个事件当子进程的stdio stream被关闭的时候触发,和exit事件的区别是多个进程可能共享同一个stdio streams!(所以一个进程退出了也就是exit被触发了,这时候close可能不会触发)

'exit'事件:

其中code表示子进程退出的时候的退出码;signal表示终止子进程发出的信号。这个事件当子进程结束的时候触发,如果进程退出了那么code表示进程退出的exit code,否则没有退出就是null。如果进程是由于收到一个信号而终止的,那么signal就是这个信号,是一个string,默认为null。

注意:如果exit事件被触发了,子进程的stdio stream可能还是打开的;Node.js为SUGUBT,SIGTERM创建信号处理器,而且Node.js进程在收到信号的时候不会马上停止。Node.js会进行一系列的清理工作,然后才re-raise handled signal。见waitpid(2)

'disconnect'事件:

在子进程或者父进程中调用ChildProcess.disconnect()方法的时候会触发。这时候就不能再发送和接受信息了,这是ChildProcess.connected就是false了

'error'事件:

当进程无法产生的时候,进程无法杀死的时候,为子进程发送消息失败的时候就会触发。注意:当产生错误的时候exit事件可能会也可能不会触发。如果你同时监听了exit和error事件,那么就要注意是否会无意中多次调用事件处理函数

'message'事件:

message参数表示一个解析后的JSON对象或者初始值;sendHandle可以是一个net.Socket或者net.Server对象或者undefined。当子进程调用process.send时候触发

child.connected:

调用了disconnect方法后就会是false。表示是否可以在父进程和子进程之间发送和接受数据,当值为false就不能发送数据了
 child.disconnect()

关闭子进程和父进程之间的IPC通道,这时候子进程可以正常退出如果没有其他的连接使得他保持活动。这时候父进程的child.connected和子进程的process.connected就会设置为false,这时候不能传输数据了。disconnect事件当进程没有消息接收到的时候被触发,当调用child.disconnect时候会立即触发。注意:当子进程为Node.js实例的时候如child_process.fork,这时候process.disconnect方法就会在子进程中调用然后关闭IPC通道。

child.kill([signal])

为子进程传入消息,如果没有指定参数那么就会发送SIGTERM信号,可以参见signal(7)来查看一系列信号

const spawn = require(&#39;child_process&#39;).spawn; 
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]); 
grep.on(&#39;close&#39;, (code, signal) => { 
 console.log( 
  `child process terminated due to receipt of signal ${signal}`); 
}); 
// Send SIGHUP to process 
grep.kill(&#39;SIGHUP&#39;);

ChildProcess对象在无法传输信号的时候会触发error事件。为一个已经退出的子进程发送信号虽然无法报错但是可能导致无法预料的结果。特别的,如果这个PID已经被分配给另外一个进程那么这时候也会导致无法预料的结果。

child.pid:

返回进程的PID值

const spawn = require(&#39;child_process&#39;).spawn; 
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]); 
console.log(`Spawned child pid: ${grep.pid}`); 
grep.stdin.end();//通过grep.stdin.end结束

child.send(message[, sendHandle][, callback])

当父子进程之间有了IPC通道,child.send就会为子进程发送消息,当子进程为Node.js实例,那么可以用process.on('message')事件接收

父进程为:

const cp = require(&#39;child_process&#39;); 
const n = cp.fork(`${dirname}/sub.js`); 
n.on(&#39;message&#39;, (m) => { 
 console.log(&#39;PARENT got message:&#39;, m); 
}); 
n.send({ hello: &#39;world&#39; });

子进程为:

process.on(&#39;message&#39;, (m) => { 
 console.log(&#39;CHILD got message:&#39;, m); 
}); 
process.send({ foo: &#39;bar&#39; });

子进程使用process.send方法为父进程发送消息。有一个特例,发送{cmd: 'NODE_foo'}。当一个消息在他的cmd属性中包含一个NODE_前缀会被看做使用Node.js核心(被Node.js保留)。这时候不会触发子进程的process.on('message')。而是使用process.on('internalMessage')事件,同时会被Node.js内部消费,一般不要使用这个方法。sendHandle这个用于给子进程传入一个TCP Server或者一个socket,为process.on('message')回调的第二个参数接受。callback当消息已经发送,但是子进程还没有接收到的时候触发,这个函数只有一个参数成功为null否则为Error对象。如果没有指定callback同时消息也不能发送ChildProcess就会触发error事件。当子进程已经退出就会出现这个情况。child.send返回false如果父子进程通道已经关闭,或者积压的没有传输的数据超过一定的限度,否则这个方法返回true。这个callback方法可以用于实现流控制:

下面是发送一个Server的例子:

const child = require(&#39;child_process&#39;).fork(&#39;child.js&#39;); 
// Open up the server object and send the handle. 
const server = require(&#39;net&#39;).createServer(); 
server.on(&#39;connection&#39;, (socket) => { 
 socket.end(&#39;handled by parent&#39;); 
}); 
server.listen(1337, () => { 
 child.send(&#39;server&#39;, server); 
});

子进程接受这个消息:

process.on(&#39;message&#39;, (m, server) => { 
 if (m === &#39;server&#39;) { 
  server.on(&#39;connection&#39;, (socket) => { 
   socket.end(&#39;handled by child&#39;); 
  }); 
 } 
});

这时候server就被子进程和父进程共享了,一些连接可以被父进程处理,一些被子进程处理。上面的例子如果使用dgram那么就应该监听message事件而不是connection,使用server.bind而不是server.listen,但是当前只在UNIX平台上可行。
下面的例子展示发送一个socket对象(产生两个子进程,处理normal和special优先级):

父进程为:

const normal = require(&#39;child_process&#39;).fork(&#39;child.js&#39;, [&#39;normal&#39;]); 
const special = require(&#39;child_process&#39;).fork(&#39;child.js&#39;, [&#39;special&#39;]); 
// Open up the server and send sockets to child 
const server = require(&#39;net&#39;).createServer(); 
server.on(&#39;connection&#39;, (socket) => { 
 // If this is special priority 
 if (socket.remoteAddress === &#39;74.125.127.100&#39;) { 
  special.send(&#39;socket&#39;, socket); 
  return; 
 } 
 // This is normal priority 
 normal.send(&#39;socket&#39;, socket); 
}); 
server.listen(1337);

子进程为:

process.on(&#39;message&#39;, (m, socket) => { 
 if (m === &#39;socket&#39;) { 
  socket.end(`Request handled with ${process.argv[2]} priority`); 
 } 
});

当socket被发送到子进程的时候那么父进程已经无法追踪这个socket什么时候被销毁的。这时候.connections属性就会成为null,因此我们建议不要使用.maxConnections。注意:这个方法在内部JSON.stringify去序列化消息

child.stderr:

一个流对象,是一个可读流表示子进程的stderr。他是child.stdio[2]的别名,两者表示同样的值。如果子进程是通过stdio[2]产生的,设置的不是pipe那么值就是undefined。

child.stdin:

一个可写的流对象。注意:如果子进程等待读取输入,那么子进程会一直等到流调用了end方法来关闭的时候才会继续读取。如果子进程通过stdio[0]产生,同时不是设置的pipe那么值就是undefined。child.stdin是child.stdio[0]的别名,表示同样的值。

const spawn = require(&#39;child_process&#39;).spawn;  
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]);  
console.log(`Spawned child pid: ${grep.pid}`);  
grep.stdin.end();//通过grep.stdin.end结束

child.stdio:

一个子进程管道的稀疏数组,是 child_process.spawn()函数的stdio选项,同时这个值被设置为pipe。child.stdio[0], child.stdio[1], 和 child.stdio[2]也可以通过child.stdin, child.stdout, 和 child.stderr访问。下面的例子中只有子进程的fd1(也就是stdout)被设置为管道,因此只有父进程的child.stdio[1]是一个流,其他的数组中对象都是null:

const assert = require(&#39;assert&#39;); 
const fs = require(&#39;fs&#39;); 
const child_process = require(&#39;child_process&#39;); 
const child = child_process.spawn(&#39;ls&#39;, { 
  stdio: [ 
   0, // Use parents stdin for child 
   &#39;pipe&#39;, // Pipe child&#39;s stdout to parent 
   fs.openSync(&#39;err.out&#39;, &#39;w&#39;) // Direct child&#39;s stderr to a file 
  ] 
}); 
assert.equal(child.stdio[0], null); 
assert.equal(child.stdio[0], child.stdin); 
assert(child.stdout); 
assert.equal(child.stdio[1], child.stdout); 
assert.equal(child.stdio[2], null); 
assert.equal(child.stdio[2], child.stderr);

child.stdout:

一个可读流,代表子进程的stdout。如果子进程产生的时候吧stdio[1]设置为除了pipe以外的任何数,那么值就是undefined。其值和child.stdio[1]一样

以上是详解从Node.js的child_process模块来学习父子进程之间的通信的示例代码的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript的角色:使网络交互和动态JavaScript的角色:使网络交互和动态Apr 24, 2025 am 12:12 AM

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

C和JavaScript:连接解释C和JavaScript:连接解释Apr 23, 2025 am 12:07 AM

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

从网站到应用程序:JavaScript的不同应用从网站到应用程序:JavaScript的不同应用Apr 22, 2025 am 12:02 AM

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python vs. JavaScript:比较用例和应用程序Python vs. JavaScript:比较用例和应用程序Apr 21, 2025 am 12:01 AM

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C/C在JavaScript口译员和编译器中的作用C/C在JavaScript口译员和编译器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)