how to do javascript await on user input in an async function
Based on @hikmat-gurbanli's answer, here is a working solution. The idea is to save the resolve function so some handle can call it in the future to unblock the async function.
const fetch = require('node-fetch')
var savedResolve;
test("http://localhost/prod/te.php");
async function test(url) {
await checkRemote(url)
console.log("completed")
}
var popupClosed = new Promise(function(resolve, reject) {
// create popup close handler, and call resolve in it
console.log("got here")
savedResolve = resolve;
});
async function checkRemote(url1) {
var resp
resp = await fetch(url1).then(r => r.text())
console.log("resp " + resp)
//setState({showPopup: true}) //in a reactjs app
var result = await popupClosed;
console.log("result: ")
console.log(result)
}
A handler can just call savedResolve.resolve("Yes")
and it will unblock the async function checkRemote
at line var result = await popupClosed;
Simple util function
const timeout = async ms => new Promise(res => setTimeout(res, ms));
let next = false; // this is to be changed on user input
async function waitUserInput() {
while (next === false) await timeout(50); // pauses script
next = false; // reset var
}
Usage example with jQuery:
// just change the value of `next` for the script to continue
$('#user-input').click(() => next = true);
async function myFunc() {
// do stuff before
await waitUserInput(); // wait until user clicks
// do stuff after
}
myFunc() // launch function and start waiting for user input
Please see this working snippet
// this is an async timeout util
const timeout = async ms => new Promise(res => setTimeout(res, ms));
let next = false; // this is to be changed on user input
let n = 1;
async function waitUserInput() {
while (next === false) await timeout(50); // pause script but avoid browser to freeze ;)
next = false; // reset var
}
async function myFunc() {
$('#text').append(`* waiting user input...<br>`)
await waitUserInput();
$('#text').append(`* user has clicked ${n++} time(s)<br>`)
myFunc()
}
$('#user-input').click(() => next = true)
myFunc()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='user-input' style='padding:15px;color:white; background: tomato; border: 0; border-radius:8px; font-weight: bold'>CLICK ME !</button>
<div id='text'>
</div>
Further improvements: store the user value
The variable next
could be used to store the user input value like this:
const userResponse = await waitUserInput(); // get user input value
// this is an async timeout util
const timeout = async ms => new Promise(res => setTimeout(res, ms));
let next = false; // this is to be changed on user input
async function waitUserInput() {
while (next === false) await timeout(50); // pause script but avoid browser to freeze ;)
const userInputVal = next;
next = false; // reset var
return userInputVal;
}
async function myFunc() {
$('#text').append(`* waiting user input...<br>`)
const userResponse = await waitUserInput();
$('#text').append(`* user choice is ${userResponse}<br>`)
myFunc()
}
$('#user-input').click(function() { next = $('#text-input').val() })
myFunc()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='text-input' type='text'/>
<button id='user-input' style='padding:15px;color:white; background: tomato; border: 0; border-radius:8px; font-weight: bold'>SUBMIT !</button>
<div id='text'>
</div>