[英]Call JavaScript class method synchronously
I'm building a package with JavaScript which has two functions: init
and sendData
. 我正在使用JavaScript构建一个包,它有两个函数:
init
和sendData
。
class Client {
init() {
return axios.post(this.baseUrl).then((response) => {
this.token = response.data.token
})
}
sendData() {
return axios.post(this.baseUrl, {token: this.token})
}
}
The init
method needs to be called before the sendData
method as this returns a token. 需要在
sendData
方法之前调用init
方法,因为这会返回一个标记。 Is there a way to wait for the init method to be called before calling the sendData
method? 有没有办法在调用
sendData
方法之前等待调用sendData
方法?
Do you need the consumer of your API to do this? 您是否需要API的使用者才能执行此操作?
// within an async function
const client = new Client();
await client.init();
await client.sendDate();
// or anywhere just using promises
const client = new Client();
client.init().then(() => client.sendDate());
or the API itself? 还是API本身?
// definition
class Client {
async init() {
const response = await axios.post(this.baseUrl);
this.token = response.data.token;
}
async sendData() {
await this.init(); // call init before sending data
return axios.post(this.baseUrl, {token: this.token})
}
}
// usage somewhere in an async function
const client = new Client();
client.sendDate() // calls init, then sends the data
Maybe remove the redundant calls if the token doesn't change? 如果令牌没有改变,可能会删除冗余调用?
class Client {
async init() {
const response = await axios.post(this.baseUrl);
this.token = response.data.token;
}
async sendData() {
if (!this.token) { // now you'll only call init for missing token
await this.init();
}
return axios.post(this.baseUrl, {token: this.token})
}
}
// usage somewhere in an async function
const client = new Client();
await client.sendDate(); // calls init (only the first time), then sends the data
Do note that promise returning functions are inherently asynchronous so there isn't a way of obtaining their result in a synchronous manner. 请注意,promise返回函数本质上是异步的,因此无法以同步方式获取结果。 However, we can write the asynchronous code using async/await to make it syntactically look (almost) identical to a synchronous version.
但是,我们可以使用async / await编写异步代码,使其在语法上看起来(几乎)与同步版本相同。
Asynchronous initialization is a good use case for the factory pattern. 异步初始化是工厂模式的一个很好的用例。 Instead of doing the asynchronous work after constructing the class, do it before and keep the constructor synchronous.
而不是在构造类之后进行异步工作,而是在之前执行并保持构造函数同步。 In my opinion a synchronous constructor that does simple assignment has the least "smell" and is the easiest to test.
在我看来,执行简单赋值的同步构造函数具有最少的“气味”并且是最容易测试的。
class Client {
constructor(baseUrl, token) {
this.baseUrl = baseUrl;
this.token = token;
}
async create(baseUrl) {
const response = await axios.post(baseUrl);
return new Client(baseUrl, response.data.token);
}
async sendData() {
return axios.post(this.baseUrl, {token: this.token})
}
}
...
const client = await Client.create('http://foo.com');
const response = await client.sendData();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.