Rahul Deora
Rahul Deora

Reputation: 167

Non-async function not being found in javascript

If the function below, called getData, is defined as an async function then it is being found later when called in the body. However if only 'async' is removed while defining it, then we get the error "ReferenceError: getData is not defined". Why is this happening? How does a function being defined as async or not affect when it is registered in the global scope?

Define a function in the head tag as:

<script>
    async function getData() {
        const x =[] 
        const y =[]
        const response=await fetch('data.csv');
        
        console.log('response revieved');
        const data = await response.text();
        console.log(data);

        split=data.split('\n').slice(1);

        split.forEach(row => {
            columns=row.split(',')
            x.push(columns[0])
            y.push(columns[1])
        });
        return{x,y}

    
}
</script>

Then later this is called in body tag as

const data = getData()

Upvotes: 0

Views: 111

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074268

How does a function being defined as async or not affect when it is registered in the global scope?

It doesn't, but removing async from that function causes a syntax error on the await. You should be seeing that in your browser console and/or build tools output. You can't have await inside a non-async function. So since it causes a syntax error, the function doesn't get created, nor does anything else in that script.

Example:

function getData() {
        const x =[] 
        const y =[]
        const response=await fetch('data.csv');
        
        console.log('response revieved');
        const data = await response.text();
        console.log(data);

        split=data.split('\n').slice(1);

        split.forEach(row => {
            columns=row.split(',')
            x.push(columns[0])
            y.push(columns[1])
        });
        return{x,y}

    
}

If you want to make that a non-async function, you have to convert the await to promise callbacks, like this (see also some other notes):

function getData() {
    return fetch("data.csv")
    .then(response => {
        // *** Side note: This check was missing
        // More in my blog post: http://blog.niftysnippets.org/2018/06/common-fetch-errors.html
        if (!response.ok) {
            throw new Error(`HTTP error ${response.status}`);
        }
        return response.text();
    })
    .then(data => {
        const x = [];
        const y = [];

        // *** Side note: Was missing `const` (or `let`)
        const split = data.split('\n').slice(1);

        // *** Side note: This could be a `for-of` loop, which might be clearer
        split.forEach(row => {
            // *** Side note: Was missing `const` (or `let`)
            const columns = row.split(',');
            x.push(columns[0]);
            y.push(columns[1]);
        });
        return {x, y}
    });
}

But note that it still does most of its work asynchronously. It has to, because of the nature of fetch.

I'd leave it as an async function. They're supported in all modern environments.

Upvotes: 4

Ali
Ali

Reputation: 136

Because await need an async function, async transform the function to a promise and then you could use await take a look at this to learn more: https://learnjsx.com/category/2/posts/es6-promise

Upvotes: -1

Related Questions