jQuery同步REST API调用无法返回对象

时间:2017-03-14 17:11:54

标签: javascript jquery rest asynchronous

我正在主线程中进行同步REST API调用。 jQuery(或浏览器?)抱怨。但我不知道如何异步编码,或者至少代码不那么令人困惑,无法按原样阅读。

这是我正在做的简化版本:

<html>
    <head>
        <script type="text/javascript" src="/js/jquery.min.js" ></script>
    </head>
    <body>
        <script type="text/javascript">
            function get_foobar(val1, val2){ 
                $.ajax({
                    url: 'http://localhost:8000/api/' + va1 + '/' + val2,
                    success: function (data) {
                       let my_object = $.parseJSON(data)
                       //console.log(data);
                       console.log(my_object);
                       let params = my_object['params'];
                       let blob = my_object['the_thing'];
                       var foobar = new FooBar(var1, var2, params, blob);

                       return foobar;  // <- object created here ...
                    },
                    async: false                    
                });

            }

            $(document.ready(function(){
                foobar = get_foobar($('#field1').val, $('#field2').val());
                console.log(foobar); // <- undefined here ... wtf?
            });
        </script>
    </body>
</html>

为什么函数不返回创建的foobar对象?

4 个答案:

答案 0 :(得分:0)

回调解决方案:

$startTimes     = @("12:30am","6am","9am","12pm","3pm","6pm")
$triggers = @()
foreach ( $startTime in $startTimes )
{
    $trigger = New-ScheduledTaskTrigger -Daily -At $startTime -RandomDelay (New-TimeSpan -Minutes $jitter)
    $triggers += $trigger
}

答案 1 :(得分:0)

这里有几个问题。

  1. 您没有在get_foobar中退回任何内容。
  2. 您无法访问成功回调的返回值。
  3. 您绝不能使用async: false
  4. 解决此问题的常用方法是使用Promises

    function get_foobar(val1, val2) {
        return new Promise(function(resolve, reject) {
            $.ajax({
                url: 'http://localhost:8000/api/' + va1 + '/' + val2,
                success: function (data) {
                   let my_object = $.parseJSON(data)
                   //console.log(data);
                   console.log(my_object);
                   let params = my_object['params'];
                   let blob = my_object['the_thing'];
                   var foobar = new FooBar(var1, var2, params, blob);
    
                   resolve(foobar);  // <- resolve the object created here ...
                },
                error: function(err) {
                    reject(err); // REJECT any errors that occur in request
                }              
            });
        });
    }
    
    get_foobar($('#field1').val, $('#field2').val())
        .then(function(foobar) {
            console.log(foobar)
        })
        .catch(function(error) {
            console.error('something went wrong!', error);
        });
    

答案 2 :(得分:0)

这是一个显示您遇到的问题的示例,以及异步获取数据的正确方法(遗憾的是,同步制作Ajax请求是不好的做法,将来会从浏览器中删除对它的支持,所以你绝对不应该依赖它。)

主要问题是,当您的异步代码运行时,调用它的函数早已完成运行并且已经返回。在此示例中,您希望像timer1这样的函数返回结果,但它会将结果返回到setTimeout的内部代码,实际调用它。 setTimeout不返回任何内容(因此undefined)。您需要做的是使用promises或简单的情况,回调。下面代码中的第二个示例使用回调在异步操作之后运行其他代码。

我建议您阅读:https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop。它将帮助您理解JavaScript中的异步代码,以及为什么事情按照它们的工作方式工作。

&#13;
&#13;
var log = (function(){
  var out = document.querySelector('#out');
  return function(msg){
    out.innerHTML += '<div>' + msg + '</div>';
  }
})();


function getSomethingAsyncTheWrongWay(){
  setTimeout(function timer1(){
    log('Round 1: First in code, last in console');
    return 'Result';
  }, 1000);
}


log(getSomethingAsyncTheWrongWay());

log('Round 1: Last in code, first in console');


function getSomethingAsyncTheRightWay(callback){
  setTimeout(function timer2(){
    log('Round 2: First in code, last in console');
    callback('Result');
  }, 1000);
}

getSomethingAsyncTheRightWay(function(result){
  log(result);
});

log('Round 2: Last in code, first in console');
&#13;
#out{
  color:green;
  background:#000;
  font-family:courier new;
  padding:1em;
  font-weight:bold;
}
&#13;
<div id=out></div>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您将无法直接将'blobby'返回到内存变量中。

将'blobby'传递给全局变量。

请尝试以下方法之一:

JQuery - Storing ajax response into global variable

Jquery - Store Ajax jSON response as variable