由于Javascript默认情况下是单线程的,这意味着代码不能创建新的线程来并行执行。而Nodejs和JavaScript相差也不大,并且它还引入了非阻塞的 I/O ,从而将异步的概念扩展到了文件访问、网络调用等。因此在Nodejs中使用异步编程就是通过回调函数来实现。把回调函数作为参数传递进方法里,方法内部执行完毕后再执行回调函数。在Nodejs中使用了大量的回调函数,Node 所有 API 都支持回调函数。
functionreadFile(filePath, callback) { // I/O 读取文件底层逻辑// ...callback(); }
非阻塞写法
constfs=require("fs"); fs.readFile('file.txt', function (err, data) { if (err) { returnconsole.error(err); } console.log(data.toString()); }); console.log("read file end.");
这种写法应当是先输出 read file end.
的内容,然后才输出文件里的内容。
阻塞写法
constfs=require("fs"); constdata=fs.readFileSync('file.txt'); console.log(data.toString()); console.log("read file end.");
而阻塞写法是先输出文件里的内容,然后才输出 read file end.
的内容。
回调地狱
JavaScript的语法中,回调的设计有效的解决了同步处理的问题,但是如果每一层函数都要依赖回调函数的返回值来进行下一步的操作的时候,就会嵌套出很多层代码,陷入这个回调地狱。这种代码非常难维护和阅读。
比如:
fs.readFile('file1.json', (err, data) => { if (err!==null) { fs.readFile('file2.json',(err,data) =>{ // ... callback }) } })