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

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.

Related

Dealing with errors in promises that are unanticipated and thus don't trigger reject() [duplicate]

This question already has answers here:
Is it an anti-pattern to use async/await inside of a new Promise() constructor?
(5 answers)
Closed 1 year ago.
In the following javascript code, why does the error (generated by the assignment to an non-existing object property inside the promise) not get caught by the .catch() on the promise, but does get caught by the window.onunhandledrejection function? I would like to be able to catch errors in my promises using .catch() even if they are not errors I have thought of in advance and thus haven't thought to write code to explicitly call reject().
window.onunhandledrejection = function( error ) {
console.log(error.reason);
};
function test() {
return new Promise( async function( resolve, reject ) {
objectThatDoesntExist.property = 1;
} );
}
test().catch( (error) => { console.log("Caught " + error) } );
Remove the async from the new Promise( async function( ...)) and it works as expected. That async is catching the exception and turning it into a rejected promise which the promise is not expecting. It is not part of the contract with the new Promise() constructor that you pass it a function that returns a promise that it should pay attention to.
Instead, the Promise constructor catches synchronous exceptions in the executor function or waits for you to call the resolve() or reject() callbacks and pays zero attention to whatever is returned from the executor callback function.
You can see here that if you remove the async keyword, then it works as expected and the exception is caught in the .catch().
function test() {
return new Promise(function( resolve, reject ) {
objectThatDoesntExist.property = 1;
} );
}
test().catch( (error) => { console.log("Caught " + error) } );
Note: One might ask "why" the Promise constructor doesn't support the case when it's made async. It seems like a promise-friendly thing to do. I don't know the actual logic that went into the decision not to support that, but I do know that whenever you're using async inside a new Promise() executor function, that's typically a sign that you don't need the new Promise() wrapper at all. If you're using async for a reason, then you already have promises. If you already have promises, then you typically don't need to wrap it in new Promise() as you can use/return the promises you already have.

Handle pending promise while using async await [duplicate]

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.

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.

Node.js - call async method without using promise third party library in nodejs [duplicate]

This question already has answers here:
How do I convert an existing callback API to promises?
(24 answers)
Closed 5 years ago.
I am new to Node.js programming. I came to know about promise object. But one of my colleagues faced an interview question.
Without using any third party promise libraries which are available in npm(example Promise, bluebird), I need to implement a promise function which returns then() and catch() function like below.
asyncPromise().then().catch()
For example:
function asyncFunction(cb){
//-----------
cb(err,data);
}
function asyncPromise(){
}
We need to Wrap a function around that function that it will make it behave as a promise. How can we achieve this with both of above functions, without using the third party libraries?
Promises are built into node and the latest versions of node have implemented support for async/await functions. Here are two ways you could do what they want. I prefer the second method.
function asyncFunc(){
return new Promise((resolve, reject) => {
if(someError){
// triggers .catch callback
return reject('There was an error');
}
// triggers .then callback
return resolve();
});
}
asyncFunc.then(() => { /* do something */ }).catch(e => { // do something });
Using async/await
function asyncFunc(){
return new Promise((resolve, reject) => { resolve() });
}
async function caller(){
let dataFromPromise;
try{
dataFromPromise = await asyncFunc();
} catch(e){
// do something with error
}
// do something with dataFromPromise
}

Categories