1)如果您运行的是单线程,则不必担心多线程应用程序带来的问题。这包括 2 个不同的线程试图同时使用同一个对象。例如,想象一下,如果一个线程试图从哈希中读取数据,而另一个线程正在从同一个哈希中删除数据。键/值对可能看起来像是存在于一行代码中,但由于在它到达下一行时的线程化,数据可能不再存在。同样,您不必处理避免这些问题所涉及的所有额外代码和麻烦。
2) 见#1。与其说是权衡,倒不如说是个问题。如今,许多计算机都有多个处理器/内核,因此让程序一次使用多个线程可能是有益的。当您期望线程阻塞时,它也很有用。例如,在另一种多线程语言中,读取文件的内容并在不添加回调的情况下输出它们是很常见的。但是,这意味着线程在文件读取操作完成之前什么都不做(阻塞)。多线程编程也很难正确完成。
3) 你不会得到保证的订单。如果要确保正确的顺序,请等待执行第二个调用,直到第一个调用返回。例如
fs.readFile('treasure-chamber-report.txt', function(report) {
sys.puts("oh, look at all my money: "+report);
fs.writeFile('letter-to-princess.txt', '...', function() {
sys.puts("can't wait to hear back from her!");
});
});
请注意,这有时会使您陷入通常所说的“回调地狱”
编辑:解决您的意见:
1)即使您正在“等待”NodeJS 来读取文件,但在 NodeJS 中,这是一个非阻塞操作。这意味着方法调用 ( readFile
) 会立即返回,甚至在读取文件之前。这是因为它将数据 IO 请求传递给底层操作系统,底层操作系统有自己的线程来处理此类请求。当操作系统完成读取(或写入)时,它会通知原始进程它已准备好接收数据。当操作系统在做这项工作时,NodeJS 可以让它的一个线程在等待时继续做其他工作。这就是你需要回调的原因——你需要一种方法来告诉 NodeJS 当你最终获得数据时下一步该做什么。
2)回调地狱本质上没有什么不好的,除了它很难阅读。有人可能会想象,如果您尝试做的事情包括几个不同的异步过程(例如读取和写入磁盘),您可能会得到如下所示的内容:
var doSomething function(){
fs.readFile('step1.txt', function(result){
// do something with the result
fs.writeFile('step2.txt', function(){
// okay, step2 is ready, so process that
fs.readFile('step2.txt', function(result){
fs.writeFile('step3.txt', function(){
//etc, etc
});
});
});
});
}
您可以看到嵌套会很快变得相当深,并且难以阅读。如果你搜索“JavaScript 回调地狱”,这里和其他地方会有很多讨论这个问题。扁平化事物的一种方法是避免使用内联/匿名函数,并使用命名函数将其扁平化,因此您的回调不会嵌套在编辑器中那么深(尽管从词法的角度来看嵌套仍在发生)。