简体   繁体   English

等待从javascript函数返回直到满足条件

[英]Wait to return from a javascript function until condition met

This is an odd problem. 这是一个奇怪的问题。 I have a client object that I am building up using Crockford-esque public/private members: 我有一个客户端对象,我正在使用Crockford式公共/私人成员构建:

var client = function() {
  var that, remote_data, other_data; 

  // add public interface
  that.doStuff = function(){...}

  // wait for remote resources to load
  remote_data = jsonRequest1();
  other_data  = jsonRequest2();

  return that;
};

The problem I'm having is that I need to load some remote JSON resources prior to returning the new 'that' object (which signals a ready client). 我遇到的问题是我需要加载一些远程JSON资源,然后再返回新的'that'对象(它指示就绪客户端)。 Data is returned asynchronously (obviously), and I am setting boolean variables to indicate when each remote resource has returned. 数据以异步方式返回(显然),我设置布尔变量以指示每个远程资源何时返回。

I've thought about doing something like the following: 我想过做以下事情:

return whenInitialized(function() { return that; });

The whenInitialized function returns whether or not both of the boolean flags are true. whenInitialized函数返回两个布尔标志是否为真。 I'd use this with a combination of setInterval, but I am sure this won't work. 我将它与setInterval的组合一起使用,但我确信这不起作用。

Would appreciate your suggestions. 非常感谢您的建议。

In order to run code after an asynchronous operation has succeeded, you need a continuation . 为了异步操作成功运行代码,您需要继续 It can be just a callback that your code calls when the operations are complete. 它可以只是代码在操作完成时调用的回调。

Something like this: 像这样的东西:

var client = function(done) { // done is the callback
  var that, remote_data, other_data; 

  // add public interface
  that.doStuff = function(){...}

  // wait for remote resources to load
  var done1 = false, done2 = false;
  var complete1 = function() { done1 = true; if (done2) done(); };
  var complete2 = function() { done2 = true; if (done1) done(); };
  remote_data = jsonRequest1(complete1);
  other_data  = jsonRequest2(complete2);

  return that;
};

But these controlling flags are really annoying and don't really scale. 但是这些控制标志真的很烦人,并没有真正扩展。 A better, declarative way of doing this is using something like jQuery deferreds : 一个更好的,声明性的方法是使用像jQuery deferreds这样的东西:

$.when(jsonRequest1(), jsonRequest2()).then(done);

You can do a loop (optionally with a timeout) to wait for the async to finish. 您可以执行循环(可选择使用超时)以等待异步完成。 Warning, this will (as requested) block all other functionality and may cause the browser to freeze if it takes much too long. 警告,这将(根据要求)阻止所有其他功能,并可能导致浏览器冻结,如果它需要太长时间。 However, you really should figure out an asynchronous way to do what you need instead of blocking like this. 但是,你真的应该找到一种异步方式来做你需要的而不是像这样阻塞。

var syncRequest = function(options) {
    var is_finished = false;
    var result;
    var finished_callback = function(response) {
        is_finished = true;
        result = response.result;
    }

    ajax_request(options, finished_callback);

    // timeout in 30 seconds
    var timeout = (new Date()).getTime() + 30000;
    while ( !is_finished ) {
        if ( (new Date()).getTime() >= timeout ) {
            alert('Request timed out');
        }

        // do nothing, just block and wait for the request to finish
    }

    return result;
}

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

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