阻止JavaScript执行,直到响应完成。

5
我是一名有用的助手,以下是您需要翻译的内容:

我有一个返回表格数据行的js代码。当点击这些行时,它们会展开,计划通过调用另一个ajax请求显示该行的子数据。

我的子数据代码如下:

function format ( d ) {
    var results;
    $.ajax({ url: 'http://127.0.0.1:7101/MUDRESTService/rest/v1/feedbacks/' + 
    d.FeedbackId + '/child/MudFeedbackDetailsVO?onlyData=true',
            
             type: 'get',  
             dataType: 'json',    
             success: function(output) {
    console.log(output.items[0].CriticalPath) ; 
                        results =      output.items[0];        
                }
       
           });
    return  results.CriticalPath;
}

问题可能是该方法没有在返回results.CriticalPath的值之前结束。我可以在Chrome JS控制台中看到值,因此数据部分没有问题。
那么,我应该如何使其在响应准备就绪后返回值?

1
使用 Promise 可能吗? - durrrr
我也在寻找一种暂停代码或等待结果的方法,但我担心这可能是不可能或几乎不可能的。异步代码在所有同步代码执行完成后才会执行,因此这将非常复杂。 - x13
不,你真的不想阻止JavaScript执行并冻结你的页面。 - Bergi
3个回答

1

在编写异步代码时,你需要开始使用回调而不是返回值。

你的函数(如此处的format)仅启动一个操作。UI的更新由回调函数发起。

与其使用以下逻辑:

function doSomething() {
   var result = format(d);
   doSomethingWithResult(result);
}

你需要适应这个:
function doSomething() {
   var result = format(d, doSomethingWithResult);
}

function format( d, callback ) {
   $.ajax(..., { 
      success : function(output) {

          var results = output.items[0];
          callback(results); // this is where we call doSomethingWithResult

      }
   });
}

如果OP和我一样,不喜欢回调地狱,该怎么办? - x13
1
不需要回电,谢谢。 - Vik
@Vik 或许在只有少量这些的小型应用程序中可以使用。 - x13
1
@ThisNameBetterBeAvailable:你链接的文章包含了如何避免混乱的回调代码的答案。我在这里不评论样式。OP有一个非常具体的错误,而回调是解决方案。避免回调地狱并不意味着不使用回调,而是要以非混乱的方式编写它们。你永远不想用长时间运行的操作阻塞UI线程。 - David Hedlund
@DavidHedlund 好的,那我误解了问题。我以为 OP 想要阻止一个非阻塞调用。 - x13

1

我并不是这方面的专家,但希望您能从代码示例中找到有用的东西。

我在.done()函数上绑定了每一行,该函数调用另一个api。希望这可以帮到您。

JS-FIDDLE

(function(){
    //getJSON example
    var jqxhr = $.getJSON( "https://api.myjson.com/bins/2emll", function(data) { 

        for (key in data) {
            $("#list").append("<li class='" + key + "'>" + data[key] + "</li>");
        }

    }).done(function( data ) {

        $("#list li").on("click", function(e){

            var target = e.target.className;

            //ajax example
             $.ajax({ 
                url: 'https://api.myjson.com/bins/309x5',         
                type: 'get',
                data: target,
                dataType: 'json',    
                success: function(data) {
                    var title = $("." + target).text();
                    $("." + target).html(title + '<ul id="ul-' + target + '"></ul>'); 
                }

           }).done(function(data){

                for (key in data) {
                    $("#ul-" + target).append("<li class='" + key + "'>" + data[key] + "</li>");
                }

           });

        });
    });
})();

抱歉,我是个完全的初学者。能否用我上面的代码写出来? - Vik
OP要求阻止非阻塞异步代码执行,而不是在完成时如何做某事。此外,他想暂停代码并等待结果,他可能不想要回调地狱。 - x13
1
我已经更新了我的回答,并发布了JS-fiddle演示。 - Salmin Skenderovic

0

你可以尝试将async选项设置为false

像这样

function format ( d )     
{  
   var results;
   $.ajax({ 
             url: 'http://127.0.0.1:7101/MUDRESTService/rest/v1/feedbacks/' +   d.FeedbackId + '/child/MudFeedbackDetailsVO?onlyData=true',
             type: 'get',
             dataType: 'json',
             async:false,    
             success: function(output) 
                {
                    console.log(output.items[0].CriticalPath) ; 
                    results =      output.items[0];        
            }
       });
return  results.CriticalPath;
}

注意:

将ajax设置为同步可能会导致浏览器无响应,因此在使用之前需要注意以下几点。

默认情况下,所有请求都是异步发送的(即默认为true)。如果您需要同步请求,请将此选项设置为false。跨域请求和dataType: "jsonp"请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,禁用任何操作,直到请求完成。从jQuery 1.8开始,使用async: false与jqXHR($.Deferred)已被弃用;您必须使用成功/错误/完成回调选项来代替jqXHR对象的相应方法,例如jqXHR.done()或已弃用的jqXHR.success()。

Ajax中的第一个字母代表“异步”,这意味着操作并行进行,完成顺序不能保证。$.ajax()的async选项默认为true,表示在请求完成后可以继续执行代码。强烈不建议将此选项设置为false(从而使调用不再是异步的),因为它可能会导致浏览器无响应。

如需了解更多信息,请阅读此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接