Javascript异步返回值

Javascript Asynchronous Return Value

本文关键字:返回值 异步 Javascript      更新时间:2023-09-26

正如我认为我了解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;
}

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

编辑

所以我错误地认为这是一个作用域问题,但这是由于AMD的异步特性。

我如何在同一方法的require作用域中返回page的值而没有while循环检查未定义?

编辑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;
});

您确实正确理解了作用域。内部函数中的代码确实给外部作用域中的变量赋值。

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

您应该能够认识到,因为undefined首先记录,并且回调中的日志语句(与对象一起)稍后执行,即使它在代码中出现在上面。

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

两个可能的原因…你和箱子不匹配。或者给page赋值的回调函数还没有执行。我猜是后者,因为如果你的case失败了,它会很明显。查看你使用的任何AMD库的文档,看看传递给require的函数是如何执行的。

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