简体   繁体   English

异步/等待不按我期望的那样

[英]Async/Await Not Waiting as I expect it

Please bear with me I've been dropped into a new project and trying to take it all in. I've been making progress over the last couple of day but can't seem to get over this last hump. 请允许我,我已经投入一个新项目并尝试将其全部投入使用。在过去的两天里,我一直在取得进展,但似乎无法克服最后的困难。 Hopefully I can explain it correctly. 希望我能正确解释。

I'm loading up a web form and need to make a call out to the API to get some information that may or may not be present based on the data currently loading up. 我正在加载一个Web表单,并且需要对API进行调用,以基于当前加载的数据获取一些可能存在或可能不存在的信息。 I've simplified my page to basically be this. 我已经简化了页面,基本上就是这样。

...Get some information the user wants and start to do some work to load 
up the page and set up the form.
...old stuff working fine...

//Time for my new stuff
var testValue
async function test() {
    await http.post(appConfig.serviceRootUrl + '/api/XXX/YYY', 
    { mProperty: myObject.collectionInObject.itemInCollection }).then(function (result) {
        if (result.length < 1) {
            testValue= false;
        }
        else if (result[0].infoIWant.trim().length > 0) {
            testValue= true;
        }
    });
}
test(); 

//Originally above in the if I was just seeing if I got a result 
//and setting testValue to true/false but changed it for debugging 
//and I am surely getting back correct values when the data exists 
//or result.length zero when no data for it


...Do a bunch of more stuff that is old and working correctly....

//Test the new stuff up above

 alert(testValue);

Most of the time I get back the correct true or false in the alert but once in a while I get back undefined. 大多数情况下,我会在警报中获得正确的对或错,但有时我会返回不确定的状态。 I'm guessing the undefined is because it is getting to the alert before the async/await finishes. 我猜未定义是因为它正在异步/等待完成之前进入警报。 I was under the impression it won't go past the line where I call "test();". 我的印象是它不会超出我称之为“ test();”的那一行。 I thought it was in effect making it halt anything below test(); 我以为它实际上使它停止了test()以下的任何内容; until the await finished. 直到等待结束。 Originally it was a bit more complex but I keep stripping it down to make it (hopefully) more basic/simple. 最初它有点复杂,但我一直在简化它,以使其(希望)更加基础/简单。

What am I missing in my thoughts or implementation? 我的想法或执行过程中缺少什么?

Any help greatly appreciated as I'm chasing my tail at this point. 非常感谢您在此刻追逐我的尾巴。

This isn't how async functions work. 这不是异步功能的工作方式。 The function only appears to wait inside the function itself. 该功能似乎只在功能本身内部等待。 Outside the function it is called and returns a promise synchronously. 在函数之外,它被调用并同步返回promise。

In other words if you write: 换句话说,如果您写:

 let t = test()

t will be a promise that resolves when test() returns. t是一个承诺,它将在test()返回时解决。 In your current code, if you want to respond outside the function you would need something like: 在当前代码中,如果要在函数之外进行响应,则需要类似以下内容:

async function test() {
    let result = await http.post(appConfig.serviceRootUrl + '/api/XXX/YYY', 
    { mProperty: myObject.collectionInObject.itemInCollection })
    if (result.length < 1) return false
    else if (result[0].infoIWant.trim().length > 0)  return true;
}


// test is an async function. It returns a promise.
test().then(result => alert("result: " + result ))

Edit based on comments 根据评论进行编辑
Here's a working version using Axios for the http.post command: 这是将Axios用于http.post命令的工作版本:

 async function test() { let result = await axios.post('https://jsonplaceholder.typicode.com/posts', { mProperty: "some val" }) return result.data } // test is an async function. It returns a promise. test().then(result => console.log(result )) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script> 

How about doing this? 怎么样呢?

...Get some information the user wants and start to do some work to load 
    up the page and set up the form.
    ...old stuff working fine...

    //Time for my new stuff
    var testValue
    async function test() {
       let promise = new Promise( (resolve, reject) => resolve( http.post(appConfig.serviceRootUrl + '/api/XXX/YYY', 
        { mProperty: myObject.collectionInObject.itemInCollection }).then(function (result) {
            if (result.length < 1) {
                testValue= false;
            }
            else if (result[0].infoIWant.trim().length > 0) {
                testValue= true;
            }
        })));
     await promise;
 alert(testValue);
    }
    test(); 

    //Originally above in the if I was just seeing if I got a result 
    //and setting testValue to true/false but changed it for debugging 
    //and I am surely getting back correct values when the data exists 
    //or result.length zero when no data for it


    ...Do a bunch of more stuff that is old and working correctly....

    //Test the new stuff up above

If you use .then() syntax, don't await , and vice versa. 如果使用.then()语法,请不要await ,反之亦然。 I was incorrect about browser compatibility with async/await, seems I haven't kept up with browser scripting, in favor of Node. 我对浏览器与async / await的兼容性不正确,似乎我并没有跟上浏览器脚本的发展,而赞成Node。 But also, since you're using jQuery, $.ajax() might be a good option for you, because you don't need async/await or .then() , and you can do like so: 而且,由于您使用的是jQuery,因此$.ajax()可能是一个不错的选择,因为您不需要async / await或.then() ,您可以这样做:

$.ajax(appConfig.serviceRootUrl + '/api/XXX/YYY', {
    method: 'POST',
    data: { mProperty: myObject.collectionInObject.itemInCollection }
}).done(function(data) {
    //use result here just as you would normally within the `.then()`
})

I hope this is more helpful than my original answer. 我希望这比我的原始答案更有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM