如何在异步功能中等待用户输入的JavaScript

时间:2018-06-24 19:45:53

标签: javascript asynchronous async-await

我遇到了一种情况,要求我关闭窗口,以便用户在关闭后根据用户输入进行选择并提出另一个http请求。弹出窗口后,我不知道如何等待。

async function checkRemote(url1, url2)  {

    var resp
    resp = await fetch(url1).then(r => r.json())

    if (r.condition1 == 100) {
        setState({showPopup: true}) //in a reactjs app
        //how do I do await here to wait for the popup being closed
        //get the user choice in variable "proceed"
    }
    if (proceed) {
        resp = await fetch(url2)
        //do some more work
    }
}

3 个答案:

答案 0 :(得分:1)

创建一个promise,在弹出窗口关闭的事件处理程序中解析它,然后在您的函数中等待它。

var popupClosed = new Promise(function(resolve, reject) {
   // create popup close handler, and call  resolve in it
});

async function checkRemote(url1, url2)  {

    var resp
    resp = await fetch(url1).then(r => r.json())

    if (r.condition1 == 100) {
        setState({showPopup: true}) //in a reactjs app
        var closed = await popupClosed;
    }
    if (proceed) {
        resp = await fetch(url2)
        //do some more work
    }
}

答案 1 :(得分:1)

这是一个简单的例子:

// this is an async timeout util (very useful indeed)
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 ;)
    next = false; // reset var
    console.log('user input detected');
}

这是jQuery应用程序的示例:


async function myFunc() {
    // do stuff
    await waitUserInput();
    $('#text').append('* user has clicked<br>')

    await waitUserInput();
    $('#text').append('* user has clicked second time')
    // next bit
}

$('#user-input').click(() => next = true)

myFunc() // launch function and start waiting for user input

请参阅此有效的演示

// this is an async timeout util (very useful indeed)
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 ;)
    next = false; // reset var
    console.log('user input detected');
}

async function myFunc() {
    // do stuff
    await waitUserInput();
    $('#text').append('* user has clicked<br>')

    await waitUserInput();
    $('#text').append('* user has clicked second time')
    // next bit
}

$('#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>

答案 2 :(得分:0)

根据@ hikmat-gurbanli的回答,这是一个可行的解决方案。这样做的目的是保存resolve函数,以便将来有一些句柄可以调用它来解除阻塞异步函数。

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)
}

处理程序只需调用savedResolve.resolve("Yes"),它将在行checkRemote上取消阻塞异步功能var result = await popupClosed;