提问者:小点点

如何“等待”异步超级()构造函数?


我正在尝试使用来自NodeJS的PayPal API REST,所以我必须用Axios进行异步调用,但我是在分离的类上这样做的,我有两个类:

const axios = require("axios");

/**PayPal main class, this class will setup PayPal credentials when instance */
class PayPal {

   constructor() {
        return new Promise(async (resolve, reject) => {
            await this.setupEnvironment();
            resolve();
        });
    }

    setupEnvironment = async () => {
        
        // Sets base URL to send requests
        this.setAPIDomain();

        // Sets PayPal endpoints
        this.setPayPalEndpoints();

        // Sets API Keys
        await this.setAPIKeys();

    }

    setAPIKeys = async () => {

        const paypal_credentials = this.getPayPalCredetials();
        const { client_id, client_secret } = paypal_credentials;

        try {

            const response = await axios({
                method: "post",
                url: this.endpoints.get_access_token,
                data: "grant_type=client_credentials",
                headers: {
                  "Accept-Language": "en_US",
                  "Accept": "application/json"
                },
                auth: {
                    username: client_id,
                    password: client_secret
                },
            });

            this.access_token = response.data.access_token;
            
        } catch (error) {
            console.log(error.response.data);
            throw new Error(error.response.data.error_description);
        }


    }

}

class Customer extends PayPal() {

    constructor() {
        super();
        // Customer class do some others actions
    }

}


$paypal_gateway = new Customer();

正如您所看到的,在PayPal类中有一个方法(setAPIKeys),它向PayPal发送一个生成mi访问令牌的请求,如果我放入console.log(this.access_token),我将得到我的访问令牌,但是只有当我把它放入setAPIKeys方法中时才会发生这种情况(这里我省略了这个类的一些方法)。

如果我把console.log($paypal_gateway.access_token)放到super()左边,我就会变得没有定义,这是显而易见的,因为PayPal类构造函数返回了一个承诺,但是在Customer类构造函数中,我只是调用了super()方法,而没有使用异步方式,我试着把“async”放到super()左边,但是没有用,我也试过:

class Customer extends PayPal {

    constructor() {

        return new Promise(async (resolve, reject) => {
            // Call to parent constructor
            super();

            // Set Customer properties
            this.setCustomer();
            resolve();
        });

    }

}

但是也不起作用,如果我把console.log(this.access_token)放在super()函数下,我也会变得没有定义,所以我不知道该做什么来等待super()构造函数,您能帮我吗?


共2个答案

匿名用户

构造函数必须返回一个对象--具体地说是在其中定义它的类的实例。它不能返回承诺,而这正是异步函数所做的。则必须执行设置步骤。您可以创建一个异步工厂函数,该函数实例化对象并执行所有设置步骤,然后返回结果对象。

async function createPaypal {
  const paypal = new PayPal()
  await paypal.setupEnvironment()
  return paypal;

}

匿名用户

我使用@SDGLuck注释来解决这个问题,我避免了构造函数方法,并实现了一个异步初始化方法:

const axios = require("axios");

/**PayPal main class, this class will setup PayPal credentials when instance */
class PayPal {

    setupEnvironment = async () => {
        
        // Sets base URL to send requests
        this.setAPIDomain();

        // Sets PayPal endpoints
        this.setPayPalEndpoints();

        // Sets API Keys
        await this.setAPIKeys();

    }

    setAPIKeys = async () => {

        const paypal_credentials = this.getPayPalCredetials();
        const { client_id, client_secret } = paypal_credentials;

        try {

            const response = await axios({
                method: "post",
                url: this.endpoints.get_access_token,
                data: "grant_type=client_credentials",
                headers: {
                  "Accept-Language": "en_US",
                  "Accept": "application/json"
                },
                auth: {
                    username: client_id,
                    password: client_secret
                },
            });

            this.access_token = response.data.access_token;
            
        } catch (error) {
            console.log(error.response.data);
            throw new Error(error.response.data.error_description);
        }


    }

}

class Customer extends PayPal() {

    async init = () => {
        await this.setupEnvironment();
        // More init code
    }

}

const paypal_gateway = new Customer();
await paypal_gateway.init(); // <- code inside another async function

希望这对其他人有所帮助,非常感谢!

相关问题