flo
flo

Reputation: 671

Nested async/await in expressjs fetch

My API-middleware code below works so far. I really want to be sure to not have any blocking calls in my express server. So I also made my function which contains the fetch async.

My question is, is that necessary at all? Because actually the first await should already unblock my express server, right?

Here is the code:

var express = require('express')
var router = express.Router()
const asyncMiddleware = require('./utils/asyncMiddleware');

async function fetchCall(URL, bodyJson, wpToken) {      
    try {        
        return await fetch(URL, {
            method: "POST",
            credentials: "same-origin",
            headers:  {
                "Authorization": "Bearer " + wpToken,
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
            body: bodyJson
    });
    } catch (error) {       
        return {status:544, error:error};
    }
}

router.post("/registerVendor", asyncMiddleware(async (req, res, next) => {              
    const response = await fetchCall(myApiUrl, req.body, 1)
    return res
    .status(response.status)
    .send({ data: response});
}));

module.exports = router

Upvotes: 1

Views: 732

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074238

If the question is, do you have to put your fetch in a separate async function, the answer is no, you don't have to. It may be useful to, but you don't have to. As you say, if you directly await the fetch promise, that will end the synchronous portion of your async route callback.

My question is, if this function ("fetchCall" in my code example) HAS to be async.

No, it doesn't. It doesn't even have to return a promise, because you can await any value. For example, the following logs A, B, C, D, and E in order:

async function foo() {
    console.log("B");
    await 42;
    console.log("D");
}

console.log("A");
foo()
.then(() => {
    console.log("E");
})
.catch(error => {
    console.error(error);
});
console.log("C");

In your case, of course, you want to return a promise. :-) This would work:

function fetchCall(URL, bodyJson, wpToken) {      
    return fetch(URL, {
        method: "POST",
        credentials: "same-origin",
        headers:  {
            "Authorization": "Bearer " + wpToken,
            "Content-Type": "application/json",
            "Accept": "application/json"
        },
        body: bodyJson
    })
    .catch(error => ({status:544, error:error}));
}

That said, the advantage to async/await is that it makes writing asynchronous code with the branching and looping constructs we're familiar with from synchronous code possible...

Upvotes: 2

Related Questions