【问题标题】:Return value from Ajax call into Javascript function从 Ajax 调用返回值到 Javascript 函数
【发布时间】:2019-11-20 04:44:46
【问题描述】:

我正在使用 Ajax 调用将数据发送到 PHP 脚本,并且我打算在 Javascript 函数中使用 Ajax 返回值。

我尝试过使用return $.ajax({}),但它不起作用。我还尝试在我的 Ajax 调用中注册一个回调函数,但效果不佳。是不是有什么事情没做呢?

function click_to_showResult() {
    var score;
    if (userName !="") {
        var result = getResultData();
        //display result for selected user
        if (result == "Distinction") {
            score ="A";
        } else if (result =="Pass") {
            score ="C";
        } else {
            score ="User has no result in DB";
        }
    }

    alert(score);

}

function getResultData(callback) {
    var data;
    var userName = $.trim($("#user").val().toLowerCase()); //gets username input from the user
    $.ajax({
        type:"POST",
        url : "getResult.php",
        data: {'name':user},
        success: function(resp) {
            data = resp;
        },
        error: function(resp) {
            alert('Error occured');
        }
    });
    return data;
}               

假设用户输入Mike,那么它应该将变量发送到PHP并为Mike获取结果(例如Pass),然后提醒C

【问题讨论】:

  • ajax,顾名思义,本质上默认是asynchronous,因此函数可以在响应之前返回。为了使用响应,请使用fetch 或将ajax 调用包装在Promise
  • @RamRaider 你能给我一个关于如何使用 Promise 实现这一点的线索。我还在学习 Ajax。
  • @RamRaider... 为什么要在这个 const click_to_showResult=function(e) 中声明常量。有必要吗?
  • 不,不是。它是定义函数的另一种方式,但可以轻松使用旧式符号function click_to_showResult(){}
  • 您应该始终正确地对代码进行空格和缩进。否则你将无法再阅读它,并且很难找到错误。我试图通过编辑你的问题来为你做这件事。

标签: javascript php


【解决方案1】:

你应该像这样使用回调。

function click_to_showResult() {
  var userName = $.trim($("#user").val().toLowerCase()); //gets username input from the user
  if (userName != "") {
    getResultData(userName, function (err, result) {
      if (err) { console.log(err); return; }
      var score;
      //display result for selected user
      switch (result) {
        case "Distinction":
          score = "A";
          break;
        case "Pass":
          score = "C";
          break;
        default:
          score = "User has no result in DB";
      }
      alert(score);
    });
  }
}

function getResultData(userName, callback) {
  $.ajax({
    type: "POST",
    url: "getResult.php",
    data: { 'name': userName },
    success: function (resp) {
      callback(null, resp);
    },
    error: function (resp) {
      callback('Error occured');
    }
  });
} 

【讨论】:

  • 请解释这一行:callback(null, resp);。为什么是空参数?
  • @Jay 该回调的第一个参数保留给error。如果您查看错误回调,则会使用第一个参数为'Error occured' 调用回调。所以在成功回调时,null 参数表示没有错误。
  • @phuwin..tnx 你的解释。现在很清楚了
【解决方案2】:

如果我理解正确,那么您也许可以像这样重写上面的代码 - 回调将处理响应并提醒用户。在发表上述评论后,我发现的一个问题是您发送的数据是 user,但这似乎没有在函数中定义 - 我怀疑您的意图是 userName?!

const click_to_showResult=function(e){

    let userName=$.trim( $('#user').val().toLowerCase() );
    if( userName!='' ){

        /* callback function to process the response data */
        const gradecallback=function( r ){
            let score;
            switch( r ){
                case 'Distinction':score='A';break;
                case 'Pass':score='C';break;
                default:score='User has no result in DB';break;
            }
            alert( score );
        };

        $.ajax({
            type: 'POST',
            url : 'getResult.php',
            data: { 'name':userName },  /* previously supplying user rather than userName */
            success: function( resp ){
                gradecallback.call( this, resp );
            },
            error: function(resp){
                alert('Error occured');
            }
        }); 
    }
}

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' ){
        ob_clean();
        /* 
            do db lookup or whatever tasks the getResults.php 
            script actually does and send the response.

            For the purposes of the demo send back some data
            which might or might not reflect the actual data
            from getResult.php... 

            Open the console to view output
        */
        $name=$_POST['name'];
        $score=mt_rand(0,100);

        if( $score >= 75 )$grade='Distinction';
        elseif( $score > 50 && $score < 75 )$grade='Merit';
        elseif( $score > 40 && $score < 50 )$grade='Pass';
        else $grade='Fail';


        $payload = json_encode( array( 'name'=>$name, 'score'=>$score, 'grade'=>$grade ) );


        /*
            sleep is used ONLY to indicate that this backend process MIGHT take some time to perform ALL
            the actions that are done by getResult.php
        */
        sleep( 2 );
        exit( $payload );
    }
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8' />
        <script src='//code.jquery.com/jquery-latest.js'></script>
        <script>
            document.addEventListener('DOMContentLoaded',e=>{

                let SCORE=false;


                /* AJAX function bound with a promise to send POST requests only */
                const ajax=function(url,params){
                    return new Promise( function( resolve, reject ){
                        let xhr=new XMLHttpRequest();
                        xhr.onload=function(){
                            if( this.status==200 && this.readyState==4 ){
                                /* 
                                The request has completed and the response is available. 
                                Resolve the Promise with the response data
                                */
                                resolve( this.response )
                            }
                        };
                        xhr.onerror=function( error ){
                            reject( error )
                        };
                        xhr.open( 'POST', url, true );
                        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                        xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                        xhr.send( params );
                    });
                };

                const alt__click_to_showResult=function(){
                    /*
                        asynchronous functions do not necessarily complete in the order
                        you would imagine like a standard synchronous function does
                        which is why returning a value from them is harder
                    */
                    console.info('called before asynchronous request bound in a Promise');

                    let url=location.href;
                    let params='name='+document.getElementById('user').value;

                    ajax( url, params ).then(
                        res=>{
                            /* The Promise has been resolved */
                            console.info('The asynchronous request has now completed - trigger ajax callback');
                            return ajax_callback( res );
                        }
                    ).then(
                        /* this is the value returned by the ajax_callback */
                        res=>{ 
                            console.info( 'The ajax callback returned this data: %o',res );
                            return true;
                        }
                    ).then(
                        res=>{
                            alert( 'all done....'+res )
                        }
                    ).catch(
                        /* For some reason the promise was rejected*/
                        e=>{ alert(e) }
                    )
                    console.info( 'After asynchronous request' );
                };

                /* do something with the data */
                const ajax_callback=function(res){
                    SCORE=JSON.parse( res );
                    console.info( 'The user "%s" scored %s which is a grade "%s"', SCORE.name, SCORE.score, SCORE.grade )
                    /* modify the data to indicate that it has been intercepted and processed - only to show flow of data*/
                    SCORE.banana='yellow';
                    return SCORE
                };





                /* a slightly modified version of previously posted function */
                const click_to_showResult=function(e){

                    let userName=$.trim( $('#user').val().toLowerCase() );
                    if( userName!='' ){

                        /* callback function to process the response data */
                        const gradecallback=function( r ){
                            let json=JSON.parse( r );// process JSON response rather than plain text as before
                            let score;

                            switch( json.grade ){
                                case 'Distinction':score='A';break;
                                case 'Merit':score='B';break;// added this...
                                case 'Pass':score='C';break;
                                default: score='User has no result in DB';break;
                            }
                            alert( 'User: '+json.name+' Scored: '+json.score+' Award: '+json.grade+' Grade:'+score );
                        };

                        $.ajax({
                            type: 'POST',
                            url : location.href, // "getResult.php"
                            data: { name:userName },  /* previously supplying user rather than userName */
                            success: function( resp ){
                                gradecallback.call( this, resp );
                            },
                            error: function(resp){
                                alert('Error occured');
                            }
                        }); 
                    }
                }

                document.querySelector( 'form > input[type="button"][name="std"]' ).addEventListener( 'click', click_to_showResult )
                document.querySelector( 'form > input[type="button"][name="alt"]' ).addEventListener( 'click', alt__click_to_showResult )
            });
        </script>
    </head>
    <body>
        <form method='post'>
            <input type='text' name='user' id='user' value='geronimo' />
            <input type='button' name='std' value='Click to show results' />
            <input type='button' name='alt' value='Alternative - Click to show results' />
        </form>
    </body>
</html>

【讨论】:

  • 它仍然没有调用。起初,很难在块中(函数内)编写等级回调函数。我必须在外部块中编写函数,然后替换这一行: const Gradecallback=function(r){。带有等级回调(r)。然后函数gradecallback(){ //语句}。没有任何输出。浏览器保持静止。
  • 不知道你为什么说“它仍然没有调用”,但是已经将上面的演示(稍作修改)和一个 Promise 绑定示例放在一起。
  • 我并不是说听起来粗鲁,我只是一个初学者,上面修改过的代码对我来说看起来很复杂。无论如何,我已经得到了解决方案。 tnx 非常感谢您为解决我的问题所做的努力
猜你喜欢
  • 2012-03-05
  • 2011-04-14
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多