【问题标题】:Javascript Asynchronous Return ValueJavascript 异步返回值
【发布时间】:2013-06-05 18:38:00
【问题描述】:

正如我以为我理解 JS 范围...

获取此代码:

function init() {

    var page;
    var pageName = $('body').data('page');

    switch(pageName) {

        // (there are more switch cases here normally...)                   

        case 'pSearchLatest':
           require(['searchresults'], function (SearchResults) {
               page = new SearchResults().init();
               console.log(page); // <- shows the object!
           });

        default:
           break;

     }

     console.log(page); // <- undefined
     return page;

}

查看控制台日志 cmets。当 var page 在 switch 语句的范围之外声明时,为什么第二个返回 undefined

编辑

所以我错误地认为这是一个范围问题,但它归结为 AMD 的异步特性。

如何在没有 while 循环检查未定义的情况下以相同的方法返回 require 范围内的页面值?

编辑 2

我是这样做的:

function init(callback) {

   case 'pSearchLatest':
      require(['searchresults'], function (SearchResults) {
          page = new SearchResults().init();
          callback(page)
      });
}

在我调用包装 init() 方法的页面中:

new PageController().init(function(asyncViewController) {
   App.view = asyncViewController;
});

【问题讨论】:

  • How to return the response from an AJAX call? 的副本——请阅读非常有帮助的问答。这个问题不是范围问题,而是时间问题。当底部log 运行时,回调尚未运行require 的回调运行 lastafter init 已终止。
  • 你期望它返回什么?
  • require 调用是异步的

标签: javascript scope


【解决方案1】:

您确实正确理解了范围。该内部函数中的代码确实分配给外部范围内的变量。

您不了解的是异步行为。 require 函数接受一个回调函数,该回调函数将在未来某个时候调用——当请求的模块可用时。然而,它会立即返回,并且控制流将导致console.log 语句,该语句会打印undefined - 这是page 变量当时的值

您应该能够认识到,由于undefined 被记录首先,并且回调中的日志语句(带有对象)稍后执行,即使它在代码中。

【讨论】:

  • 啊当然!异步模块定义。呃。谢谢,将在 9 分钟内接受:D.
  • eurgh,我如何在该 init 方法中返回页面?我想我可以做一段时间(page==undefined) 的事情,但这很恶心吧?
  • @AdamWaite while(page==undefined)工作,因为 JS 是单线程的。设置场景:您的回调正在等待触发时间,并且线程正忙于循环。有一天,回调触发;它出现在线程上并说“我现在准备好运行了!”线程说:​​“抱歉,不是现在,我正忙于运行这个循环来检查page 的值;完成后你可以运行。”回调恳求道:“但我应该为你设置 page!你不能安排我吗?”线程回复,“对不起,规则就是规则!我想我会永远运行这个循环,然后!”
  • 哈哈,我习惯用 Objective-C 和 Ruby 编写代码,所以 Javascript 总是让我大吃一惊:D。我想我已经破解了,请看我的更新。
【解决方案2】:

require 是异步的,因此您的函数确实先退出然后处理回调函数。

【讨论】:

    【解决方案3】:

    两个可能的原因……你不符合这个案例。或尚未执行将值分配给page 的回调。我猜是后者,因为如果你 case 失败了,那就很明显了。查看您使用的任何 AMD 库的文档,看看传递给 require 的函数是如何执行的。

    一般来说,尽量避免返回由这样的异步调用确定的值。而是使用某种观察者模式来订阅可以从不同位置触发的特定事件。

    【讨论】:

      猜你喜欢
      • 2012-06-04
      • 2011-09-06
      • 2016-08-25
      • 2015-06-29
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 2011-12-08
      • 2018-01-25
      相关资源
      最近更新 更多