Wait Until Flag=True

How to wait until a predicate condition becomes true in JavaScript?

You created an infinite loop where the flag value that terminates the loop can never be changed by code outside this loop because no code outside the loop ever gets to run - thus this will never work.

Because javascript in a browser is single threaded (except for webworkers which aren't involved here) and one thread of javascript execution runs to completion before another can run, your statement:

while(flag==false) {}

will simply run forever (or until the browser complains about a non-responsive javascript loop), the page will appear to be hung and no other javascript will ever get a chance to run, thus the flag's value can never be changed by code outside this loop.

For a little more explanation, Javascript is an event driven language. That means that it runs a piece of Javascript until it returns control back to the interpreter. Then, only when it returns back to the interpreter, Javascript gets the next event from the event queue and runs it.

All things like timers and network events run through the event queue. So, when a timer fires or a network request arrives, it does not ever "interrupt" the currently running Javascript. Instead, an event gets put in the Javascript event queue and then, when the currently running Javascript finishes, the next event is pulled from the event queue and it gets its turn to run.

So, when you do an infinite loop such as while(flag==false) {}, the currently running Javascript never finishes and thus the next event is never pulled from the event queue and thus the value of flag never gets changed. They key here is that Javascript is not interrupt driven. When a timer fires, it does not interrupt the currently running Javascript, run some other Javascript and then let the currently running Javascript continue. It just gets put in the event queue waiting until the currently running Javascript is done to get its turn to run.


What you need to do is rethink how your code works and find a different way to trigger whatever code you want to run when the flag value changes. Javascript is designed as an event-driven language. So, what you need to do is figure out what events you can register an interest in so you can either listen for the event that might cause the flag to change and you can examine the flag on that event or you can trigger your own event from whatever code might change the flag or you can implement a callback function that whatever code changes that flag can call your callback whenever the piece of code responsible for changing the flag value would change it's value to true, it just calls the callback function and thus your code that wants to run when the flag gets set to true will get to run at the right time. This is much, much more efficient than trying to use some sort of timer to constantly check the flag value.

function codeThatMightChangeFlag(callback) {
// do a bunch of stuff
if (condition happens to change flag value) {
// call the callback to notify other code
callback();
}
}

Wait until a condition is true?

You could use a timeout to try to re-submit the form:

$('#route-form').submit(function(event) {
// User submits form, we need their location...
if(current_location==null) {
toastMessage('Waiting for your location...');
setTimeout(function(){ $('#route-form').submit(); }, 500); // Try to submit form after timeout
return false;
} else {
// Continue with location found...
}
});

Wait until flag = true fails, flag is always false

isOrganizationCreated will always hold the initial value false, because there is never a new value assigned to the variable in the function scope of useCreateOrganization - so it is more of a basic JavaScript closure thing (if you want to read more, look at *1 down under)

The problem also is, you want to implement imperative style polling (until) in React world. Instead you should embrace the declarative nature of React by using state and props to trigger a new render cycle. So instead of polling, you could call the mockCreateOrg API, which in turns sets the new state. This new state triggers a rerender, that could lead to side effects - e.g. console.log("done").

I am not sure, why do you want to use Hooks in your sample exactly, so here is a basic fetch example with three states: When 1) the Hook is in "idle", 2) the organization is being created ("pending"), 3) orga creation has completed ("created").

Codesandbox

import * as React from "react";
import { render } from "react-dom";
import { useEffect, useState } from "react";

export const useCreateOrganization = (): {
createOrganization: (organizationName: string) => Promise<any>;
} => {
const [state, setState] = useState<"idle" | "pending" | "created">("idle");

useEffect(() => {
let interval;
if (state === "pending") {
interval = setInterval(() => console.log("not done yet!"), 500);
} else if (state === "created") {
console.log("done");
// ...do some other things here...
setState("idle");
}
return () => interval && clearInterval(interval);
}, [state]);

// Fakes org creation on a server.
const mockCreateOrg = (orgName: string) => {
setTimeout(() => {
setState("created");
}, 1500);
};

const createOrganization = async (organizationName: string): Promise<any> => {
mockCreateOrg(organizationName);
setState("pending");
};

return { createOrganization };
};

function App() {
const { createOrganization } = useCreateOrganization();
const handleCreateOrg = () => {
createOrganization("New Org Name");
};

return (
<div className="App">
<button onClick={handleCreateOrg}>Start process</button>
</div>
);
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

Further info: closures in React Hooks (*1)

When you invoke the closure createOrganization, it will use the variable isOrganizationCreated defined in the outer scope (useCreateOrganization function body), which at invocation time has the initial state value false. isOrganizationCreated will always have the literal value false in this scope, a reassignment never happens (with const also not possible). By triggering a state change with setIsOrganizationCreated, React internally updates its component memory cell, and with a new render cycle invokes useCreateOrganization again - now with the updated isOrganizationCreated state. Though that doesn't change the closure scope of the first useCreateOrganization invocation.

Hope, it helps.

C# Wait until condition is true

At least you can change your loop from a busy-wait to a slow poll. For example:

    while (!isExcelInteractive())
{
Console.WriteLine("Excel is busy");
await Task.Delay(25);
}

Coffeescript wait until flag is set from a callback and then move on to the next part of the code

There are probably a few ways you can achieve this, where we wait until your flag end_program or clean from your code is set to true by your socket.on 'data' method.

At the end of the script, you can use a function that continuously returns a promise until a certain condition is met (in this case, the flag clean is set).

The Q library you are using should suffice as I believe its .delay function is async. For example, in the below code, the function checks the flag every second, and if the flag is not set, the function will call itself again, checking after another second. If the flag is set, we can then move on to the next part of the code.

This may look something like this, using the variable clean as your flag:

waitForFlag = () -> 
Q.delay(1000).then ->
if (clean)
console.log "Condition met! We can move on"
else
# if condition isn't met, check again in one second
waitForFlag()

# Call function
waitForFlag().then ->
process.exit(0)

Javascript - pause execution until flag becomes true

It's really a bad idea to use some kind of a flag. You have to use Deferred Pattern. Something like this:

var resources = [];
$(_response).find('ACTION').each(function() {
var deferred = resources.length > 0 ? resources[resources.length - 1] : null;

switch (tagName) {
case "RESOURCEUPDATE":
deferred = $.Deferred();

//load the resource with selected id in an iframe
$(iframe).bind('load', function () {
deferred.resolve(/*specific arg1, arg2, arg3, ...*/)
});
resources.push(deferred);
break;
case "EVENT":
if (deferred) {
deferred.done(function (/*specific arg1, arg2, arg3, ...*/) {
// process event node
});
}
break;
}
});

// clean up deferreds objects when all them will be processed
$.when.apply($, resources).then(function() {
resources.length = 0;
})

P.S.: http://api.jquery.com/category/deferred-object/

Javascript wait for condition to be true using promises

You have to return a promise:

function waitForCondition(conditionObj) {
return new Promise(resolve => {
var start_time = Date.now();
function checkFlag() {
if (conditionObj.arg == conditionObj.test) {
console.log('met');
resolve();
} else if (Date.now() > start_time + 3000) {
console.log('not met, time out');
resolve();
} else {
window.setTimeout(checkFlag, 1000);
}
}
checkFlag();
});
}

async function run() {
console.log('before');
await waitForCondition({arg: '1', test: '1'})
console.log('after');
}
run();

I refactored your code a bit. To get the current time, use Date.now(). And you should be OK with calling resolve without a timeout of 1 millisecond.



Related Topics



Leave a reply



Submit