How to create a Sync version of an Async method? - javascript

I'm trying to achieve something similar to the methods you get with the core fs module where you have an Async method by default and a Sync method if requested such as fs.readDir() and fs.readDirSync();
I have a method called fetchUrls that fetches files from a list of urls and returns a promise. I want to add another method called fetchUrlsSync which calls fetchUrls and blocks the thread until the promise is resolved. how can that be done?
sample code:
fetchUrls(startDate, endDate) {
return new Promise((resolve, reject)=> {
// some async work...
})
}
fetchUrlsSync() {
// call fetchUrls and block until resolved
}
those two functions are methods on a class.

This isn't possible directly in node.js. It also goes against the general model in node, which is to perform all IO asynchronously.
It is however possible to use a compiled Node.js extension to achieve this called http-sync.

Related

PowerBi Embedded report.getFilters() - convert promise to syncronous

My page uses PowerBi embedded and I want to be able to return in javaScript the current filters in the report back to the server.
The call is easy enough, just call report.getFilters() in javaScript.
Unfortunately for me it returns a promise. How can I convert this to a syncronous call?
https://learn.microsoft.com/en-us/javascript/api/powerbi/powerbi-client/report.report
There are many methods to handle the asynchronous property in JavaScript. I used one of them that is async/await.
It is used for writing asynchronous code in JavaScript to make code behave in a synchronous way.
The word async used before the function means it always returns a promise. If a function returns a non-promise value, the async function returns like a resolved promise. And await works only inside async function and it makes JavaScript wait until the promise settles and returns the result.
Code:
async function getfilter() {
const embedContainer = $('#embedContainer')[0];
report = powerbi.get(embedContainer);
// Get the filters on the report page
const filter= await report.getFilters();
console.log('The filters on the report is:', filter)
}
Output:
[1]: https://i.stack.imgur.com/K532I.png
you can also refer to- https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

Expo FileSystem.writeAsStringAsync doesn't act like a Promise

I'm using the function Expo.writeAsStringAsync()
(docs: https://docs.expo.io/versions/latest/sdk/filesystem/#filesystemwriteasstringasyncfileuri-contents-options).
I noticed that it needs different times with different size files (as expected), but there is no way to know when it has finished, because it returns nothing. So, if I have to access the file just after writing it, I could find it empty, because maybe it's still writing.
Is there any way to receive an answer when it has completed? like a normal promise-then-catch?
P.S.: I've tried to promisify it, but without success.
I can see that the API docs are misleading because they don't specify the return type.
In fact that API call is defined as async function (see source-code):
export async function writeAsStringAsync(
fileUri: string,
contents: string,
options: WritingOptions = {}
): Promise<void> {
// ...
}
Every async function returns a Promise (you can see in TypeScript signature above it says Promise<void>).
This means you can use the returned Promise and await for it or use .then() to wait for the moment of filesystem call to complete.
await Expo.writeAsStringAsync(fileUri, contents, options);
// do something when write is finished
// you can catch errors with try/catch clause
or
Expo.writeAsStringAsync(fileUri, contents, options).then(
() => { /* do something when write is finished */ }
).catch(err => { /* handle errors */ }

Return data async inside emit

I have a background process written in node.js that is using the EventEmitter like this:
var event = { returnValue: undefined };
eventEmitter.emit('name', event, argument);
return event.returnValue; // Example of doing things with event.returnValue.
Other end of the event:
eventEmitter.on('name', (event, argument) => {
var returnValue = await asyncMethod(); // <- This method returns a Promise, so I could use await if possible or some other solution.
event.returnValue = returnValue;
});
I've tried to find an elegant solution to use asynchronous methods, but since EventEmitter does not support asynchronous functions at all, I can't really use await in the function or something similar.
One solution could be to set returnValue to a Promise, but that quickly becomes impractical, specially since some of my functions iterate through multiple asynchronous functions.
I need all the code to complete properly before the first block of code continues and tries to use the event.returnValue.
Is my only solution to use some third party "synchronize", or hasn't anyone at node.js thought of this problem?
There isn't really any problem for me if the thread is blocked while executing, since this is a background process without any GUI.
Since it doesn't really seem to exist any intuitive way to wait for a Promise to resolve synchronously without callbacks, or to use the EventEmitter with async callbacks, I wrote my own simple EventEmitter containing an array, and custom on and emit methods.
It handles asynchronous functions used as parameters properly so I can use it like this:
asyncEmitter.on('name', async (event, argument) => {
event.argument = await asyncMethod(); // Nice and clean code!
});
Of course I could develop it further create a once function and so on, but for me I really only depend on on and emit.
I wonder why the node team hasn't solved this yet?

Firebase Cloud Function Terminating before Database Data Downloaded

I am trying operate on all children in a Firebase Realtime Database directory, however, I am running into a problem that I cannot solve. Using the "child_added" trigger to download the data calls the function for every child in the directory. Normally using promises in this kind of situation would be fine, however, because the same function is called multiple times my function ends up continuing after the on('child_added') function is called once and missing all the other calls. I have no idea how to remedy this, all suggestions are appreciated!
Don't use child_added, because it never stops listening, and your function must terminate as soon as possible. Instead, use once('value') to fetch all the data, and make use of its returned promise to continue when its snapshot is available. It might be similar to this sample, in addition to many others in that repo.
You can still use promises, but instead of closing the function after one promise is returned wait for all promises.
I'm not sure what your Cloud Function looks like, but let's assume it's a database trigger
functions.database.ref('/some/trigger').onWrite(async event => {
const promises = [];
admin.database().ref('/some_child').on('child_added', snapshot => {
const pushRef = admin.database().ref('/some_path').push(snapshot.val()); // Some pretend async operation
promises.push(pushRef);
});
return Promise.all(promises);
}
In this example I'm listening to /some/trigger then getting all the children at the path /some_child.
I'll then save each child into a new object under /some_path.
Each promise is pushed into an array and the Promise.all will cause the function to wait for all promises (writes) to resolve.

Javascript: How to determine whether to promisefy a function?

Consider small helper functions, some of which are obvious candidates for async / promise (as I think I understand them):
exports.function processFile(file){
return new Promise(resolve => {
// super long processing of file
resolve(file);
});
}
While this:
exports.function addOne(number){
return new Promise(resolve => {
resolve(number + 1);
});
}
Seems overkill.
What is the rule by which one determines whether they should promise-fy their functions?
I generally use a promise if I need to execute multiple async functions in a certain order. For example, if I need to make three requests and wait for them all to come back before I can combine the data and process them, that's a GREAT use case for promises. In your case, let's say you have a file, and you need to wait until the file and metadata from a service are both loaded, you could put them in a promise.
If you're looking to optimize operations on long running processes, I'd look more into web workers than using promises. They operate outside the UI thread and use messages to pass their progress back into the UI thread. It's event based, but no need for a promise. The only caveat there is that you can't perform actions on the DOM inside a web worker.
More on web workers here: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
What is the rule by which one determines whether they should promise-fy their functions?
It's quite simple actually:
When the function does something asynchronous, it should return a promise for the result
When the function does only synchronous things, it should not return a promise

Categories

Resources