【发布时间】:2018-07-25 03:30:04
【问题描述】:
我正在创建一个“类”,它发出诸如error、data、downloadFile 和initialize 之类的事件。每个事件在发出请求后触发,每个事件由同名的方法触发:
class MyClass extends EventEmitter {
constructor(data) {
this.data = data
this.initialize()
.then(this.downloadFile)
.then(this.data)
.catch(this.error)
}
initialize() {
const req = superagent.post('url...')
superagent.send(data)
const res = await req // this will actually fire the request
this.emit('initialize')
this.url = res.body
return res
}
downloadFile() {
const req = superagent.put(this.url)
const res = await req; // this will actually fire the request
req.on('progress', (progress) => this.emit('downloadFile', progress)
//
// save to disk
//
return res
}
data() {
// Next in the sequence. And will fire the 'data' event: this.emit('data', data)
}
error(err) {
this.emit('error', err)
}
}
之后我就有了要调用的数据方法。我的疑问是:是否有一种设计模式可以在不使用 Promises 的情况下按顺序调用事件?目前我正在使用链接,但我觉得这不是最好的方法,也许我错了。
this.initialize()
.then(this.downloadFile)
.then(this.data)
.catch(this.error)
但我觉得这可能是一个更好的方法。
bergi 问题的答案:
a) 你为什么使用类语法?
因为从 EventEmitter 继承更容易,而且我个人认为它比使用构造函数更具可读性 函数,例如:
function Transformation(data) {
this.data = data
}
// Prototype stuffs here
b) 如何使用此代码
我正在创建一个客户端来与我的 API 交互。想法是用户可以看到后台发生的事情。例如:
const data = {
data: {},
format: 'xls',
saveTo: 'path/to/save/xls/file.xls'
}
const transformation = new Transformation(data)
// Events
transformation.on('initialize', () => {
// Here the user knows that the transformation already started
})
transformation.on('fileDownloaded', () => {
// Here the file has been downloaded to disk
})
transformation.on('data', (data) => {
// Here the user can see details of the transformation -
// name,
// id,
// size,
// the original object,
// etc
})
transformation.on('error', () => {
// Here is self explanatory, if something bad happens, this event will be fired
})
c) 它应该做什么?
用户将能够将带有数据的对象转换为 Excel。
【问题讨论】:
-
你definitely should not put the promise chain in the constructor(完全不清楚为什么这应该是
class) -
不,promise 是按顺序运行的 解决方案(你当然可以用
async/await替换你的链接,反正你已经在使用它了)。事件比较麻烦,你为什么要这么做? -
您发送了一个答案,说从构造函数返回 Promise 是一件坏事,但我不是 @Bergi
-
没错,你不会退回它,但那更糟:-D。我的答案是链接线程解释了为什么在构造函数中启动异步操作通常是一件坏事。
-
是的,我看到了,我将更改代码以避免这种情况。 @Bergi,你不觉得看到一个使用 Promises 但发出事件的实现很奇怪吗?
标签: javascript node.js class promise eventemitter