Handle pending promise while using async await [duplicate] - javascript

This question already has answers here:
Async function returning promise, instead of value
(3 answers)
Closed 2 years ago.
I have two time taking functions -> getExcelFileStream and loadWorkbook
I want the function structure to return a response(pass/failure) only after both these subfunctions have been executed.
But it always returns a promise pending clause.
async function parseToJson(data) {
const excelFileStream = await getExcelFileStream(data.url);
const dataRows = await loadWorkbook(excelFileStream, data.orgId);
return dataRows;
}
exports.uploadExcel = function uploadExcel(data) {
return parseToJson(data);
};

According to the doc (Syntax > Return value)
A Promise which will be resolved with the value returned by the async function, or rejected with an exception thrown from, or uncaught within, the async function.
So it should be
exports.uploadExcel = async function uploadExcel(data) {
return await parseToJson(data)
}

It is not possible to make an asynchronous code synchronous in javascript, and with javascript being single threaded, you can't write code to wait for the promise without blokcing the execution of the code handling the promise itself.
I am guessing when you're calling your function uploadExcel, you don't have any await or a .then() so you get a promise instead of the value of the resolved promise.
Unfortunately, You only have two options:
1- Let async/await propagates all the way up in your code
2- Make all your code synchronous, and that would be a very bad idea.

Related

Convert new Promise to Async/await in modal method [duplicate]

This question already has answers here:
How to turn this callback into a promise using async/await?
(2 answers)
Closed 8 months ago.
I have tried to convert these pieces of code to async/await. But seem it is impossible!!! Does anyone have any suggestions?
As already mentioned in comment, you can't await events that don't supply a promise interface without creating a new promise. You could, however, promisify firing of the event and process popupData.data outside of the promise executor function. The await operator will still need to be used in an async function or JavaScript module
Example in vanilla JS:
async methodName() {
if (this.notificationPopupSubscription) this.notificationPopupSubscription.unsubscribe();
const popup = await new Promise(resolve => {
this.notificationPopupSubscription = modal.onAnyCloseEventFinished.subscribe(resolve);
});
const popupData = popup.getData();
popup.removeData();
if (!popupData.data) {
throw Error("no data"); // reject promise returned by async method
}
return popupData.data; // fulfill promise ...
}
In the example, this.notificationPopupSubscription is set synchronously in the executor, but the popup variable is set after waiting for the promise to be resolved. The enclosing function/class method still needs to be called with an appropriate this value of course.

How to return a value from a promise which isn't a pending promise: d3.js, Javascript? [duplicate]

This question already has answers here:
async/await implicitly returns promise?
(5 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I am relatively new to asynchronous javascript programming. When using the d3.scv function from the d3 library, I ran into an issue where when awaiting the results of the promise from d3.csv inside a async function scope, I can directly access the resolved value, but when I return this resolved value I get a pending promise.
Code
async function generateCountryData(){
let csvData = await d3.csv("./data/data.csv", (d) => {
return {
"id" : +d["id"], // The '+' turns a string into a number
"country" : d["name"],
"faction" : +d["overlord"]
}
});
let dataArray = csvData.map(Object.values);
// LOG 1
console.log(dataArray);
return dataArray;
}
// LOG 1: Array(58)
// Returns: PromiseĀ {<pending>} "fulfilled"[[PromiseResult]]: Array(58)
async function func1() {
let result = await generateCountryData();
// LOG 2
console.log(result);
return result;
}
// LOG 2: Array(58)
// Returns: PromiseĀ {<pending>} "fulfilled"[[PromiseResult]]: Array(58)
Since I dont want to define a new async function each time I want to access this array, I want to know how I can return a defined resolved value which isn't a pending promise.
It's annoying, but this is how it works. Anything that needs access to the result of an asynchronous operation must itself be asynchronous.
So while there's different patterns for dealing with this (callbacks, observers, promises), you can't get around this so best to embrace it.
You can't turn async code into non-async code. An interesting article about this:
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/

Do not wait for a promise to execute and resolve it immediately [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I am having a downstream API call which is basically returning a Promise object instead of resolving it and executing it on point.
This is how I am calling the downstream:
const response = testClient.getSession(sessionId);
When I console.log(response) it is prinitng as Promise { <pending> } instead of desired result which it shoudl print from the downstream.
Having known very little about Async/Await, Promises etc I would like to know whihc category does it fall in? And how do I execute that promise first and do the rest of the steps.
However, I have found a temporary work around like this:
response.then(function(result) {
console.log(result.body);
});
But ideally I would want to store the result into response object then and there itself. Please help me understand this. Thanks in advance
What you called a temporary workaround using then is actually the correct way of waiting on the Promise to be fulfilled. You cannot 'force' it to be fulfilled, because the code will execute as fast as it can and allow you to carry on working until then (that's the point of promises) - but you can wait on it to be fulfilled:
You ought also to check to see if the promise gets 'rejected' using catch - ie produces an error:
response.then( function(result) {
console.log(result.body);
}).catch( function(error) {
console.log(error);
});
To use await:
async function thingy(){
const response = await testClient.getSession(sessionId);
}
To use await and check for errors:
async function thingy(){
try {
const response = await testClient.getSession(sessionId);
} catch (error) {
console.error(error);
}
}
Note that when using async, you do generally need to be in a function declared as async.
The idea of the Promise is to allow your program to carry on doing things whilst you wait for the promise to be fulfilled/rejected - for example, you might make several requests at once, and wait for them all:
Promise.all([
getStuff('one'),
getStuff('two'),
getStuff('n')
]);

How to make a Client Side javascript function to invoke an api and use api response to construct an object [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a requirement where i need to invoke an api from within a client side Javascript function and once i get the response from the api i should use the response to construct a variable value. My function looks like below. The problem i am facing is that before the function could return the complete api response the next line to calculate totalAmt gets executed and as chkresponse1 is empty then the variable totalAmt is not being calculated correctly. And FYI getCheckFinalAmount() internally invokes the api using XMLHTTPRequest.
How do i ensure that totAmt gets calculated only after the api response is obtained? Any code snippets will be very helpful.
function applePayButtonClicked() {
var chkresponse1=getCheckFinalAmount(); // this function returns the api response.
var totalAmt = ((chkresponse.totals.sub_total / 100) + (chkresponse.totals.tax / 100) + tipamt).toFixed(2).toString();
}
You can use async/await. An async function will pause at each await expression until the promise is resolved. Also it's a good idea to catch any errors with a try catch block.
async function applePayButtonClicked() {
try {
const chkresponse1 = await getCheckFinalAmount();
const totalAmt = ((chkresponse.totals.sub_total / 100) + (chkresponse.totals.tax / 100) + tipamt).toFixed(2).toString();
} catch (err) {
console.log(err);
//handle errors
}
}
This solution assumes the expression following the await operator is'awaitable', meaning it is either a Promise or it can be converted to a resolved Promise. Here's what MDN says:
The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled Promise.
If the Promise is rejected, the await expression throws the rejected value.
If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise.

Why is my async function returning too soon? [duplicate]

This question already has answers here:
async function returns Promise { <pending> }?
(2 answers)
async/await return Promise { <pending> } [duplicate]
(1 answer)
Closed 4 years ago.
I am trying to use an async function to call a function inside another function. It looks like this:
const getConnectionsWithEmailsHash = async () => {
const connectionsWithEmails = await parseConnections('./tmp/connections.csv')
console.log(connectionsWithEmails)
return connectionsWithEmails
}
const connectionsWithEmailsHash = getConnectionsWithEmailsHash()
console.log(connectionsWithEmailsHash)
When I console.log() inside the async function, I get the hash I am expecting, but when I console.log() the result of calling the async function, I get promise pending. I though the point of an async function was that it waits for the promise to be resolved when it is called, so what I am I doing wrong?
async functions return promises. This line:
const connectionsWithEmailsHash = getConnectionsWithEmailsHash()
...just sets connectionsWithEmailsHash to the promise that the function returns. To actually get the resolution value of the promise, you'd need to:
Use await within another async function (if that means using async at the top level, see: How can I use async/await at the top level?):
const connectionsWithEmailsHash = await getConnectionsWithEmailsHash()
or,
Use then on the promise
getConnectionsWithEmailsHash()
.then(connectionsWithEmailsHash => {
// ...use `connectionsWithEmailsHash`....
})
.catch(error => {
// ...handle error...
})
getConnectionsWithEmailsHash is still an async function itself. connectionsWithEmails is valid because you awaited parseConnections, but connectionsWithEmailsHash is not valid because getConnectionsWithEmailsHash is running in parallel. Try "await getConnectionsWithEmailsHash".
Now, if you want to use this on the top level, that's another question. That question is answered here.
I think you don't need a wrapper function.
const connectionWithEmailHash = await parseConnections(arg);
This should work for given code in question.
Code snippet in question won't work since async function should return a promise. So try returning a promise in getConnectionWithEmailHash that resolves with connectionsWithEmails and your code should work.

Categories