简体   繁体   English

同步调用JavaScript类方法

[英]Call JavaScript class method synchronously

I'm building a package with JavaScript which has two functions: init and sendData . 我正在使用JavaScript构建一个包,它有两个函数: initsendData

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM