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()
CodePudding user response:
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}
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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.
CodePudding user response:
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