How to block execution of a function (i.e., force synchronous behaviour)? [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
What is the JavaScript version of sleep()?
(91 answers)
Closed 3 years ago.
Requirement:
I need to write a function that takes an array of objects. Each item in the array has a state; if state === 'processing', a delay of 2 seconds is implemented before moving on to the next item. In other words, I actually need to block execution of the function for 2 seconds before looking at the next element in the array. When an element's state is not 'processing', the function returns an object and no further array elements are looked at.
The problem:
I can't think of any way to create a delay without using asynchronous approaches. I've written code (see below) which relies on Promise, but this does not satisfy the requirements, as with any asynchronous approach the Promise will return immediately; the delay only delays promise resolution not function execution. Thus, I wonder if there isn't a way of doing this synchronously, of blocking return of the function until after any delays are implemented.
My question:
Is there a way to accomplish this synchronously, to block execution of the code for a specified period of time before returning an object?
My code, which uses an asynchronous approach:
function wait(delay, callback, arg) {
return new Promise(resolve => {
setTimeout(() => {
resolve(callback(arg));
}, delay);
});
}
function getProcessingPage(data) {
const currentObj = data[0];
const state = currentObj.state;
if (state === 'processing') {
return wait(2000, getProcessingPage, data.slice(1));
}
return Promise.resolve({});
}
The solution:
Since this question has been closed (wrongly, in my opinion), it can not be answered, but I now have an answer. The answer is not performant in the least bit — it is not considered good practice and should never find its way into production code — but it does exactly what I needed to do for this exercise. The solution is to use while to prevent any code execution during the desired delay. See below:
function wait(delay) {
const delayUntil = performance.now() + delay;
while (performance.now() < delayUntil) {
// do nothing, as the while statement blocks execution
}
}
function getProcessingPage(data) {
const currentObj = data[0];
const state = currentObj.state;
if (state === 'processing') {
wait(2000);
return getProcessingPage(data.slice(1));
}
return {};
}

Related

my object is modified inside a function that has a promise even if function returned [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
console.log() async or sync?
(3 answers)
Closed 8 months ago.
i have the following function that should return a result object
function checkRegisteredStatus(addr)
{
let result ={status:"",registrationType:""};
instance.methods.isRegistered(session.id,addr).call().then((receipt)=>
{
let {status,registrationType}= receipt;
result["status"] = status;
result["registrationType"]= registrationType;
});
return result;
}
i want to use this function like this:
let result = checkRegisteredStatus(addr)
i have three problems :
1- when i used async/await pattern on isRegistered() method like this:
let result = await instance.methods.isRegistered(session.id,addr).call();
return result;
result object would be a promise with unfulfilled status, which is wired since the purpose of await is to return the result of the resolve callback, and this is the first time that happens to me, i did async/await before and it always returns the final result not a promise. why is this happening?
2- due to the first problem i had to re-write my function the old way which is using.then() method (as i pasted above) and it works, however i dont understand how come the checkRegisteredStatus function should finish execution and is popped off from the call stack then how is it being able to modify the result object?
Example:
let result = checkRegisteredStatus(addr)
console.log(result)
the output would be:
> {status:"",registration:""}
when i click the expand sign > it outputs the following:
> {status:"",registration:""}
registrationType: "NotRegistered"
status: false
as far as i understand the value was caught be console.log() when the result object still had empty properties that's why i could expand the object and see its props have different values,i think JS is adding elements from inside that promise that registered before, but the function result obj should be cleaned from the stack (since it returns immediately), how is it adding values to it even though the function is popped from the call-stack?
3- how should i rewrite my function such that it blocks execution until it returns the final result not a promise and not adding up values later.

Determine how long a promise took [duplicate]

This question already has answers here:
how much time each function takes in promis.all? [duplicate]
(2 answers)
How to measure the execution time of a promise?
(5 answers)
Closed 1 year ago.
I'm using the q library for promises. I have the following code
Q.all([thumbnailPromise, createSnapshotPromise]).spread((thumbnailRep, snapshotRep) => {
How do I determine how long each promise took? Specifically, how long thumbnailPromise and createSnapshotPromise took separately?
Note that I want to keep the promises running in parallel.
Thanks!
I guess you could write a function that wraps your promise:
const timedPromise = async (promFac) => {
const start = performance.now();
const returnValue = await promFac();
return {
value: returnValue,
elapsed: performance.now() - start;
}
}
and use it like this:
Q.all([
timedPromise(() => thumbnailPromise) ,
timedPromise(() => createSnapshotPromise)])
.spread((thumbnailRep, snapshotRep) => {
console.log(`thumbnailProm took ${thumbnailRep.elapsed}, returned ${thumbnailRep.value}`);
})
Untested.
You can use console.time(); MDN reference
Another option would be to use hrtime.
Promises are functions, if you don't have access directly to the functions, you can wrap them in one.

returning a value from async/await promise [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I am trying to find a simple example of how to return a value from async/await where the value is easily accessed outside the async function.
Would the following two examples be considered the optimum way to return a value from an async/await function?
In other words, if the value returned from an async/await needs to be saved and used in other parts of the code, what would be the best way to save the value?
this is the easiest example i could find:
async function f() {
return 1;
}
var returnedValue = null; // variable to hold promise result
f().then( (result) => returnedValue = result );
console.log(returnedValue); // 1
or perhaps would it be better to use an object?
async function f(varInput) {
varInput.value = 1;
}
myObject = {} ; myObject.value=null;
f(myObject);
console.log(myObject.value); // 1
thank you.
My answer addresses two subjects here:
1) Async function returns a promise that resolves to a value. So, for instance your first function can be used as per your example. It can also be used like this:
async function() {
const x = await f();
}
2) Immutability - the second solution will work but it makes your funciton "impure". It is not bad in itself, but beware of side effects this might cause (for instance, if you change an app-wide singleton value without other components being notified about it, some part of your app might go out of sync with the data).
Hope this answers your question.

Wait for multiple non nested callbacks [duplicate]

This question already has answers here:
How can I wait for set of asynchronous callback functions?
(8 answers)
Closed 4 years ago.
Say I have two (or more) asynchronous operations op1 and op2 that call a callback function upon completion. How do I best wait for both to complete before starting op3?
I am not able to nest them inside of each other (i.e. first starting op1, then starting op2 inside of op1callback())
(I of course also do not know which of these is going to complete first, but that doesn't really matter I guess)
function op1callback {
}
function op2callback {
}
function op3 {
...
}
The easiest would be to just keep flags about the callbacks state:
let count = 0;
function callback() {
if(++count === 2) op3();
}
op1(callback); op2(callback);
But in the long term it might be beneficial to let the operations return promises, e.g.:
async function op1() {
// Do some async stuff and *await* that
return "something";
}
then you could just do:
Promise.all(op1(), op2()).then(op3);

return value after a promise [duplicate]

This question already has answers here:
setting a variable to get return from call back function using promise
(2 answers)
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 8 years ago.
I have a javascript function where I want to return the value that I get after the return method.
Easier to see than explain
function getValue(file){
var val;
lookupValue(file).then(function(res){
val = res.val;
}
return val;
}
What is the best way to do this with a promise. As I understand it, the return val will return before the lookupValue has done it's then, but the I can't return res.val as that is only returning from the inner function.
Use a pattern along these lines:
function getValue(file) {
return lookupValue(file);
}
getValue('myFile.txt').then(function(res) {
// do whatever with res here
});
(although this is a bit redundant, I'm sure your actual code is more complicated)
The best way to do this would be to use the promise returning function as it is, like this
lookupValue(file).then(function(res) {
// Write the code which depends on the `res.val`, here
});
The function which invokes an asynchronous function cannot wait till the async function returns a value. Because, it just invokes the async function and executes the rest of the code in it. So, when an async function returns a value, it will not be received by the same function which invoked it.
So, the general idea is to write the code which depends on the return value of an async function, in the async function itself.

Categories