gpt4 book ai didi

javascript - 了解何时使用事件以及何时使用回调

转载 作者:行者123 更新时间:2023-11-29 21:09:49 24 4
gpt4 key购买 nike

对于事件,发起者引发一个事件,该事件将被那些已选择接收该事件的例程接收。接收方指定将从哪些发起方接收哪些事件。

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

所以我很困惑我应该在哪里使用事件或我应该在哪里使用回调,因为我可以完成回调对事件的处理,但会导致在应用程序中创建大量事件。

在编码、使用事件或回调时应该遵循什么好方法?

最佳答案

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

回调(或 promise )- 针对可能发生一次的事情。

因此,例如,当您调用一个函数时,因为您需要从某些 API 获取当前温度,该函数应该返回一个 promise 或接受一个回调,稍后可以用正确的值(或错误)调用该回调.

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

现在,关于何时使用回调和何时使用 promises 的问题有点棘手,因为它们适用于相同类型的情况 - 当您想知道某些异步操作的结果时(某些数据或错误).由于两者都适用于相同的情况,让我们考虑两个读取文件内容的示例。

首先,回调:

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

现在,与 promise 相同:

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);
});

它的工作原理与前面的示例完全相同。

对于这个简单的示例,区别可能不是很明显,但是如果您想要一个函数来抽象掉其中的一些逻辑怎么办。

例如,带有回调:

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

现在,与 promises 的不同之处在于,您可以将它存储在一个变量中,从一个函数中返回它,或者在附加成功/错误处理程序之前将它作为参数传递给某个其他函数。例如:

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 时附加回调() 函数。您可以在其他地方进行。

如果您不想更改错误消息,可以使用回调:

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

这是 promise :

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 与不返回 promise 的函数一起使用。

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

要在 Node v7.x 中使用 asyncawait,您需要使用 --harmony 标志,请参阅:

关于javascript - 了解何时使用事件以及何时使用回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42231996/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com