了解何时使用事件以及何时使用回叫

有了事件,发起者就会提出一个事件,这个事件将被那些select接收事件的例程接收。 接收者指定将从哪个发起者接收哪些事件。

通过callback,完成后的例程通知调用者完成。

所以我很困惑我应该在哪里使用事件,或者我应该在哪里使用callback,因为我可以完成事件的callback,但会导致在应用程序中创build大量事件。

在编码,使用事件或callback时应遵循什么样的好方法?

事件 – 对于可能发生多次的事情。

callback(或承诺) – 可以发生一次的事情。

例如,当你有一个你调用的函数,因为你需要从某个API获取一个当前的温度,那么这个函数应该返回一个promise,或者采取一个callback,稍后可以调用正确的值(或者错误)。

另一方面,如果你有一个你要调用的函数,因为每当它发生变化时都需要得到一个新的温度,那么这个函数应该返回一个事件发射器(或者把一个事件处理器附加到一些内部的事件发射器上) 。

现在,关于何时使用callback以及何时使用promise的问题有点棘手,因为它们适用于相同types的情况 – 当您想知道某些asynchronous操作(某些数据或错误)的结果时。 既然两者都在相同的情况下工作,让我们考虑阅读文件内容的两个例子。

首先,callback:

let fs = require('fs'); fs.readFile('a.txt', 'utf-8', (err, data) => { if (err) { console.log('Error:', err.message); } else { console.log('Data:', data.trim()); } }); 

如果没有文件,将会打印:

 Error: ENOENT: no such file or directory, open 'a.txt' 

如果有文件,将会打印:

 Data: Contents of a.txt 

现在,与承诺一样:

 let fs = require('mz/fs'); fs.readFile('b.txt', 'utf-8') .then(data => { console.log('Data:', data.trim()); }) .catch(err => { console.log('Error:', err.message); }); 

它和前面的例子完全一样。

对于这个简单的例子,差异可能不是很明显,但是如果你想有一个抽象的逻辑的function。

例如,使用callback函数:

 let fs = require('fs'); function a(cb) { fs.readFile('b.txt', 'utf-8', (err, data) => { if (err) { return cb('a() error: ' + err.message); } cb(null, 'a() data: ' + data.trim()); }); } a((err, data) => { if (err) { console.log('Error:', err); } else { console.log('Data:', data); } }); 

它会打印这个

 Error: a() error: ENOENT: no such file or directory, open 'a.txt' 

或者像这样的东西:

 Data: a() data: Contents of a.txt 

现在,与promise不同的是,您可以将它存储在一个variables中,从函数中返回,或者作为parameter passing给其他函数,然后再附加成功/error handling程序。 例如:

 let fs = require('mz/fs'); function a() { return fs.readFile('a.txt', 'utf-8') .then(data => 'a() data: ' + data.trim()) .catch(err => Promise.reject('a() error: ' + err.message)); } let promise = a(); promise.then(data => console.log('Data:', data)) .catch(err => console.log('Error:', err)); 

它的工作原理是一样的,它是用不同的风格写成的,你可能会发现或不会发现更多的可读性,但是不同的是,现在你不必在调用a()函数的时候附加一个callback函数。 你可以在别的地方做。

如果你不想改变错误信息,那就是callback:

 function a(cb) { fs.readFile('a.txt', 'utf-8', (err, data) => { if (err) { return cb(err); } cb(null, 'a() data: ' + data.trim()); }); 

这与承诺:

 function a() { return fs.readFile('a.txt', 'utf-8') .then(data => 'a() data: ' + data.trim()); } 

另一个区别是如果你有一个函数返回一个promise,你可以在async function使用一个新的await关键字,如下所示:

 async function x() { try { console.log('Data:', await a()); } catch (err) { console.log('Error:', err); } } 

您不能使用不返回承诺的函数await

例如,当你需要读取文件a.txt来获取它所包含的另一个文件名,然后读取另一个文件并打印它的内容,同时在更复杂的情况下处理所有错误时,它会变得非常方便。

要使用asyncawait节点v7.x,您需要使用--harmony标志,请参阅: