Home > Software engineering >  Best way to return Promise from asynchronous request?
Best way to return Promise from asynchronous request?

Time:07-03

I am trying to write an asynchronous function in TypeScript which makes an HTTP request using axios and returns a Promise for the data requested.

export async function loadSingleArweaveAbstraction(absId : string) : Promise<AbstractionPreview> {

    let abstractionPreview : AbstractionPreview = await axios({
        method: 'get',
        url: ARWEAVE_URL   absId,
        responseType: 'json'

    }).then(function(response) {
        return {
            name: response.data.name,
            imageUri: response.data.image,
            symbol: response.data.symbol,
        };
    }).catch(function(v) {
        return { name: "Null", imageUri: "null", symbol: "null" };
    });

    return abstractionPreview;
}

I am not sure if this is the best way to return the response from the asynchronous call. Do I have to use await or could I remove it and return within the then and catch blocks? Also the fact that I need the catch block to return a dummy AbstractionPreview seems very inelegant.

CodePudding user response:

Usually, you don't mix await and .then() in the same function - instead pick one style or the other for a particular function. While the code you show will work just fine, these are two more consistent ways to write it:

Without async/await:

export function loadSingleArweaveAbstraction(absId : string) : Promise<AbstractionPreview> {

    return axios({
        method: 'get',
        url: ARWEAVE_URL   absId,
        responseType: 'json'

    }).then(function(response) {
        return {
            name: response.data.name,
            imageUri: response.data.image,
            symbol: response.data.symbol,
        };
    }).catch(function(e) {
        console.log(e);
        return { name: "Null", imageUri: "null", symbol: "null" };
    });
}

Using async/await:

export async function loadSingleArweaveAbstraction(absId: string): Promise <AbstractionPreview> {
    try {
        let response: AbstractionPreview = await axios({
            method: 'get',
            url: ARWEAVE_URL   absId,
            responseType: 'json'

        });
        return {
            name: response.data.name,
            imageUri: response.data.image,
            symbol: response.data.symbol,
        };
    } catch (e) {
        console.log(e);
        return { name: "Null", imageUri: "null", symbol: "null" };
    }
}

There is no "right" way between these two. It really depends upon your own personal preferences. I tend to prefer await when I have more than one asynchronous operation that I want to sequence because it's just simpler code to read than chained .then() handlers. With only one asynchronous operation, it's more of a wash which way is simpler and up to personal preference.

Note, I always log errors that I'm consuming/hiding. Otherwise, something may go wrong in your system, your code is "eating" the error and you really end up with no idea what's going wrong.

P.S. I'm not a TypeScript person so if I've accidentally made a TypeScript syntax error, please feel free to correct it.

. It seems that in both scenarios we are waiting for our asynchronous call to fulfill its promise (await in the first example, and then in the second) and then return. Then what is the purpose of asynchronous calls? They seem to act like synchronous calls since we always wait for them to fulfill before returning?

In both cases, this function returns a promise immediately (as soon as the asynchronous axios() call is started). That allows the caller to do other things while these operations are underway. Then, when the asynchronous operation completes, these functions can process the results and set the resolved value of that original promise so the caller can get notified of the final result.

This is not synchronous code. Nodejs and the caller are able to do other things or process other events while this asynchronous operation is underway. This is non-blocking and asynchronous. await allows you to write code that may "look" like synchronous code, but an async function returns a promise at the point of the first await in the function and the caller then gets that promise and can do other things or nodejs can process other events.

Is it possible to return an unfulfilled promise?

Yes, both these options already return an unfulfilled promise. That's nearly always what you're doing when you return a promise.

  • Related