Home > OS >  Returning a value from a mix of async/sync function from a provider (different script) to express se
Returning a value from a mix of async/sync function from a provider (different script) to express se

Time:12-11

Apologies for asking this question - I know there are tons of information about async functions out there but I seem to have tried everything and cannot find a solution..

First of all let me outline the architecture of my program. There are two scripts: a main server script (node.js, express), which processes GET requests and provider script, which deals with the blockchain in the background to return some values. The server script is responsible for invoking a method that returns a value from the provider. The provider does all the work.

The snippet of the provider script:

    getInfo(index, account, key) {
    //Waiting on an asynchronous method, which does some work in the blockchain in the background; everything functions as it should be
    try {
        
        await this.getBlockchain
    (
            index    
            , account        
            , key                     

    ).then(result => {
            // Here instead I invoke a SYNCHRONOUS method, which simply formats the response in a correct way
            const reply = this.sendReply(result)
            console.log(reply) //Logs the correct reply in the format in which the server is expecting it
            return reply;
        });
    }

    catch (error) {
        return { error: 003, result: false };
    }

} 

The snippet of the server script:

    server.get("/getAccount", async (req, res) => {

let index = req.query.index;
let account = req.query.account;
let key = req.query.key;

// Here I also check for the validity of the query values, irrelevant to this issue
// The provider class is imported as provider, hence, the provider.method (this has been tested many times before)

try {

    await provider.getInfo(index, account, key).then(reply => {

        const { error: infoError, result: infoValue } = reply
        
        if (infoError == false) {

            res.send(`${infoValue}`);

        } else {

            res.send(`${infoError}`);

        };
        

    });

}

catch (error) {
    res.send("008");
}
    }

    );

I honestly have no idea how to approach this; I tried self-contained async function on the server side as well as different syntax but the reply is always undefined even though the reply from a synchronous call in the provider is correct.

Could someone help me to understand what I'm doing wrong? This is my first time working with async with numerous scripts and functions and I'm finding it very confusing.

Thank you so much!

CodePudding user response:

With your current structure, you need to return the result of the await so that the top level of your function is returning something from the async function.

    async getInfo(index, account, key) {
        try {
            let retVal = await this.getBlockchain(index, account, key).then(result => {
                return this.sendReply(result);
            });
            return retVal;
        } catch (error) {
            return { error: 003, result: false };
        }
    }

But, really, it's a better coding style to not mix await and .then() and to just go with one style like this:

async getInfo(index, account, key) {
    try {
        let result = await this.getBlockchain(index, account, key);
        return this.sendReply(result);
    } catch (error) {
        return { error: 003, result: false };
    }
}

Note, this function never rejects because it's catching its own rejections and turning it into a resolved value. So, the caller cannot use .catch() to see errors. The caller must always check for the error property in the resolved object. This is not usually how you program with promises. It can be made to work, but often does not meet the expectations of the caller (as errors are usually communicated back via rejected promises).

CodePudding user response:

This has to be a dup. but... Don't mix await and .then.

You simply try/catch around await.

try {
    const reply = await provider.getInfo(index, account, key);
    const { error: infoError, result: infoValue } = reply
    if (infoError == false) {
        res.send(`${infoValue}`);
    } else {
        res.send(`${infoError}`);
    };
} catch (error) {
    res.send(500);
}
  • Related