我有一个等待四个外部事件的函数(我无法控制它们。它们是随机接收的)
function Foo() {
var this.data_1;
var this.data_2;
var this.data_3;
var this.data_4;
}
Foo.prototype.getData = function(){
deviceOne.on('data', (data) => {
this.data_1 = data;
});
deviceTwo.on('data', (data) => {
this.data_2 = data;
});
deviceThree.on('data', (data) => {
this.data_3 = data;
});
deviceFour.on('data', (data) => {
this.data_4 = data;
});
return {
"data_from_device_1": this.data_1,
"data_from_device_2": this.data_2,
"data_from_device_3": this.data_3,
"data_from_device_4": this.data_4
}
};
var foo = new Foo();
console.log(foo.getData()); // {'undefined', 'undefined', 'undefined', 'undefined'}
如您所见,该函数不会等待它们,它将返回4个未定义的对象。我一直在寻找解决方案,似乎使用async可能会有所帮助。只是我不了解如何正确使用它
答案 0 :(得分:0)
要使用async
(在这里确实有帮助),首先您需要制作deviceXYZ.on
的Promise版本:
const waitForData = device => new Promise((resolve, reject) => {
device.on('data', (data) => {
resolve(data);
});
// ...presumably hook up some kind of error event and use `reject` here...
});
然后(由于您使用的是class
,因此我已经转换为async
语法,可以使用新的,更简单的表示法):
class Foo {
async getData() {
// ^^^^^
const data = await Promise.all([
// ^^^^^
waitForData(deviceOne),
waitForData(deviceTwo),
waitForData(deviceThree),
waitForData(deviceFour)
]);
this.data_1 = data[0];
this.data_2 = data[1];
this.data_3 = data[2];
this.data_4 = data[3];
return {
data_from_device_1: this.data_1,
data_from_device_2: this.data_2,
data_from_device_3: this.data_3,
data_from_device_4: this.data_4
};
}
}
然后,使用它的代码也必须在async
函数中:
( async () => {
// ^^^^^
try {
const foo = new Foo();
console.log(await foo.getData()); // {'undefined', 'undefined', 'undefined', 'undefined'}
// ---------^
} catch (e) {
// Handle/report error
}
})();
...或者它可以直接在非async
函数中使用promise:
const foo = new Foo();
foo.getData()
.then(result => {
console.log(result);
})
.catch(error => {
// Handle/report error
});
更多:
旁注:这是无效的语法:
function Foo() {
var this.data_1; // Error here
var this.data_2;
var this.data_3;
var this.data_4;
}
目前,您尚未在JavaScript中声明属性。但是,不久之后(可能是ES2019,几乎肯定是ES2020)class
语法将由类字段提案扩展,目前在提案流程的第3阶段。发生这种情况时,您可以声明由Foo
类创建的对象的“形状”(这意味着这些对象可以进行较少的形状更改,这有助于提高性能;它对于阅读代码的人也是有用的文档)。那将使Foo
看起来像这样:
class Foo {
data_1; // These are field (property) declarations
data_2;
data_3;
data_4;
async getData() {
// ...
}
}