同步调用JavaScript类方法

时间:2019-02-11 22:55:23

标签: javascript async-await es6-promise

我正在使用JavaScript构建一个包,该包具有两个功能:num = structure(list(Intercept = c(1L, 1L, 1L, 1L, 1L), Num1 = c(1.2, 2.39, 1.93, 1.3, 2.37), Num2 = c(0L, 1L, 1L, 0L, 1L), Num3 = c(5.46, 2.95, 13.44, 3.05, 3.55)), class = "data.frame", row.names = c(NA, -5L)) custom.boot <- function(times, data) { boots <- rep(NA, times) for (i in 1:times) { temp.se.df = NA temp.se.df = sapply(sample(data, length(data), replace=TRUE), sd)/sqrt(length(data)) boots[i] <- mean(temp.se.df) } boots } # this generates 1000 averaged SE's based on sampling of the `num` columns: custom.boot(1000, num) 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}) } } 方法之前需要调用init方法,因为这会返回令牌。有没有办法在调用sendData方法之前等待init方法被调用?

2 个答案:

答案 0 :(得分:3)

您需要使用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());

还是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

如果令牌没有更改,也许会删除多余的呼叫?

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

请注意,promise返回函数本质上是异步的,因此没有一种以同步方式获取其结果的方法。但是,我们可以使用async / await编写异步代码,以使其在语法上(几乎)与同步版本相同。

答案 1 :(得分:0)

异步初始化是工厂模式的一个好用例。构造类之前,不要做异步工作,而要使构造函数保持同步。在我看来,执行简单分配的同步构造函数的“气味”最少,并且最容易测试。

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