【问题标题】:Accessing a variable from within nested functions in Javascript从 Javascript 的嵌套函数中访问变量
【发布时间】:2013-02-12 10:51:59
【问题描述】:

我有以下功能:

downloadProductImage: function(remoteImage, localImageName){
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
        fileSystem.root.getFile(localImageName, {create: true, exclusive: false}, function(fileEntry) {
            var localPath = fileEntry.fullPath;
            var ft = new FileTransfer();
            ft.download(remoteImage,
                localPath, function(entry) {
                    //RETURN THIS imageURL = entry.fullPath;

                }, fail);
        }, fail);
    }, fail);       
}   

函数 downloadProductImage() 位于全局 var app = {} 中,因此通过 app.downloadProductImage() 访问。

此函数在循环中运行,我希望返回 imageURL 但似乎无法得到它。我在 var app = {} 之外声明了 global var = imageURL 但是每当我尝试在另一个函数中获取 imageURL 时,第一个循环返回 undefined ,其余的都是正确的。

我不确定为什么第一个循环返回 undefined.. var imageURL 在页面顶部全局声明..

如果我在上面代码中的 //RETURN THIS imageURL = entry.fullPath; 下发出警报(imageURL),它会正确发出警报,只是当我尝试在函数之外访问它时不会发出警报

【问题讨论】:

  • 您是否尝试过在对象中将 imageURL 指定为应用程序对象的一部分(即app.imageURL)并将其设置为self.imageURL,其中var self = this; 放置在ft.download 行之前。可能有帮助?
  • 您将无法返回。操作是异步的。
  • 在检查顶层的 imageURL 之前是否检查过内部函数已被调用?它可能还没有被调用。几个明智的 console.log() 调用可能会帮助您确保这里没有竞争条件。

标签: javascript function nested


【解决方案1】:

鉴于@dfsq 提到这是一个异步调用,我相信您在顶层访问它时会发现 imageURL 是未定义的,因为根本还没有调用回调。

确认这一点的最简单方法是在回调中插入两个 console.log() 语句,就在您设置 imageURL 之前和之后;和另外两个 console.log() 语句围绕您访问 imageURL 的顶级代码中的点。

如果访问确实发生在分配之前,那么这将解释为什么您会看到“未定义”。为了解决您的问题,您需要推迟在顶层执行的任何操作,直到回调完成。 jQuery Promise 是执行此操作的一种方法,但其他库中也有其他选项。在您使用的任何库中寻找“期货”、“承诺”、“延迟执行”作为关键字。如果您使用任何类型的事件框架,您也可以使用:在回调中触发事件,并在顶层监听事件(确保在触发之前监听,否则会遇到相反的问题)。

如果您使用的是 jQuery,那么以下内容可能会给您一个先机:

var imageURLPromise = jQuery.Deferred();

downloadProductImage: function(remoteImage, localImageName){
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
        fileSystem.root.getFile(localImageName, {create: true, exclusive: false}, function(fileEntry) {
            var localPath = fileEntry.fullPath;
            var ft = new FileTransfer();
            ft.download(remoteImage,
                localPath, function(entry) {
                    // Note: The assignment is mediated by the DeferredObject that handles the timing issues for us.
                    imageURLPromise.resolve(entry.fullPath);
                }, fail);
        }, fail);
    }, fail);       
}   

imageURLPromise.done(function(imageURL) {
    // Use imageURL here at toplevel.
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-16
    • 2018-10-23
    • 2013-10-17
    • 2019-06-14
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多