简体   繁体   English

Javascript 异步/等待 - 无法让它工作

[英]Javascript Async/Await - Cannot get it to work

My 1st post.我的第一篇文章。 I'm a Javascript 'hacker' (and feel much more comfortable with PHP, never gotten a hang of Javscript): I've tried for hours trying callbacks, delays, now ASYNC/AWAIT: Problem: AWAIT Code Not doing what I want.我是 Javascript 的“黑客”(并且对 PHP 感觉更舒服,从未掌握过 Javscript):我已经尝试了几个小时尝试回调、延迟,现在是 ASYNC/AWAIT:问题:等待代码没有做我想要的. I've referenced multiple examples and forums, but not turn to stack overflow in desperate frustration!我参考了多个示例和论坛,但没有绝望地转向堆栈溢出!

Note: Expanding on this existing tool: https://github.com/webismymind/editablegrid/tree/master/examples (notice it says be sure to run AJAX in Synchronous)注意:扩展此现有工具: https://github.com/webismymind/editablegrid/tree/master/examples (注意它说一定要同步运行 AJAX)

DatabaseGrid.prototype.initializeGrid = function(grid) {

  var self = this;

    grid.setEnumProvider('id_Bolt', new EnumProvider({ 

        // the function getOptionValuesForEdit is called each time the cell is edited
        // here we do only client-side processing, but you could use Ajax here to talk with your server
        // if you do, then don't forget to use Ajax in synchronous mode 
        
        getOptionValuesForEdit: **async** function (grid, column, rowIndex) {
            
            var Thread_Code = grid.getValueAt(rowIndex, grid.getColumnIndex("Thread_Code"));
            
            **let** result = **new** setBoltEnum(Thread_Code);
            *console.log(Date.now() + " - 3 - " + **await** result.array);*
            return **await** result.array;

            
        *console.log(Date.now() + " - 4 - " + "ending function");*
        
        }
    }));
};

AJAX code it is calling:它正在调用的 AJAX 代码:

setBoltEnum = function(Thread_Code){

        *console.log(Date.now() + " - 1 - calling AJAX");*
            result = $.ajax({
                url: 'EnumHelper.php',
                type: 'POST',
                dataType: "html",
                data: {
                    value: Thread_Code,
                    col_out: 'Descr',
                    col_search: 'Thread_Code',
                    tablename: 'Bolt_List'
                },
                success: function (response) {
                    result = JSON.parse(response);
                    *console.log(Date.now() + " - 2 - got AJAX response: " + result.resp);*
                    return result;
                    //_callback();
        
                },
                error: function(XMLHttpRequest, textStatus, exception) { alert("Ajax failure\n" + errortext); },
                async: true
            });
};

Output in Chrome: 1 - calling AJAX 3 - undefined 2 - Got AJAX response - ok Output 在 Chrome 中:1 - 调用 AJAX 3 - 未定义 2 - 得到 AJAX 响应 - 好的

(4) is not outputted (4) 不输出

How can I get code to run 1-2-3-4?如何让代码运行 1-2-3-4?

You can only usefully await a promise.您只能await promise。

You call setBoltEnum with new so it is treated as a constructor function and returns an object that is an instance of setBoltEnum (this doesn't make any sense because that function doesn't do anything that would be useful to use a constructor function for). You call setBoltEnum with new so it is treated as a constructor function and returns an object that is an instance of setBoltEnum (this doesn't make any sense because that function doesn't do anything that would be useful to use a constructor function for) . It certainly doesn't return a promise.它当然不会返回 promise。

setBoltEnum then calls $.ajax (which runs asynchronously) and assigns the result to result (You don't seem to have declared result so it is a global… this is probably bad, especially when dealing with asynchronous code). setBoltEnum然后调用$.ajax (异步运行)并将结果分配给result (您似乎没有声明result ,所以它是全局的……这可能很糟糕,尤其是在处理异步代码时)。 It then does nothing with that variable.然后它对那个变量什么都不做。 It has no return statement at all so even if you didn't call it with new it will wouldn't return a promise.它根本没有返回语句,所以即使你没有用new调用它,它也不会返回 promise。

Then you return await result.array;然后你return await result.array; . . There's no point in await ing as you return since you are going to be returning a promise anyway (because the function is async ).在您returnawait没有意义,因为无论如何您都将返回 promise (因为 function 是async )。 Here, result is the return value of $.ajax() which won't have an array property so the value is undefined (not a promise).在这里, result$.ajax()的返回值,它没有array属性,因此该值是undefined的(不是承诺)。

The next line is console.log but you never reach it because you just return ed.下一行是console.log ,但你永远不会到达它,因为你只是return ed。

Later the success function is called.后来success function 被调用。 This assigns a new value to result which might have an array property… but that also won't be a promise.这会为可能具有数组属性的result分配一个新值……但这也不会是 promise。


To fix this:要解决这个问题:

  • Don't use new when you aren't dealing with a constructor function不处理构造函数 function 时不要使用new
  • Don't use await when you aren't dealing with a promise or other thenable当您不处理 promise 或其他 thenable 时,请勿使用await
  • Do return promises or other thenables from functions that work asynchronously从异步工作的函数中返回 Promise 或其他 thenables
  • Don't mix callbacks ( success / error ) with promises (it just makes code hard to manage)不要将回调( success / error )与承诺混合(这只会使代码难以管理)
  • Do remember that $.ajax() returns a thenable (which you can await ).请记住$.ajax()返回一个 thenable (您可以await )。

Below code ended up working and outputted 1-2-3.下面的代码最终工作并输出了 1-2-3。 Note, I stumbled upon this (adding ASYNC/AWAIT in setBoltEnum).请注意,我偶然发现了这一点(在 setBoltEnum 中添加 ASYNC/AWAIT)。

setBoltEnum = async function(Thread_Code){

        console.log(Date.now() + " - 1 - calling AJAX");
            return await $.ajax({
                url: 'EnumHelper.php',
                type: 'POST',
                dataType: "html",
                data: {
                    value: Thread_Code,
                    col_out: 'Descr',
                    col_search: 'Thread_Code',
                    tablename: 'Bolt_List'
                },
                success: function (response) {
                    result = JSON.parse(response);
                    console.log(Date.now() + " - 2 - got AJAX response: " + result);
        
                },
                error: function(XMLHttpRequest, textStatus, exception) { alert("Ajax failure\n" + errortext); },
                async: true
            });
};


DatabaseGrid.prototype.initializeGrid = function(grid) {

  var self = this;

    grid.setEnumProvider('id_Bolt', new EnumProvider({ 

        // the function getOptionValuesForEdit is called each time the cell is edited
        // here we do only client-side processing, but you could use Ajax here to talk with your server
        // if you do, then don't forget to use Ajax in synchronous mode 
        
        getOptionValuesForEdit: async function (grid, column, rowIndex) {

            var Thread_Code = grid.getValueAt(rowIndex, grid.getColumnIndex("Thread_Code"));
            result = await setBoltEnum(Thread_Code);
            console.log(Date.now() + " - 3 - returning this: " + result);
            return result;
            //return expecting this  { "br" : "Brazil", "ca": "Canada", "us" : "USA" }; //result;

        
        }
    }));

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

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