从Javascript中的嵌套函数中访问变量

从Javascript中的嵌套函数中访问变量,javascript,function,nested,Javascript,Function,Nested,我有以下功能: downloadProductImage: function(remoteImage, localImageName){ window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) { fileSystem.root.getFile(localImageName, {create: true, exclusive: false}, function(fileEnt

我有以下功能:

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()位于全局变量app={}内,因此可由app.downloadProductImage()访问

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

我不知道为什么第一个循环返回未定义的。。var imageURL在页面顶部全局声明


如果我在上述代码中//RETURN THIS imageURL=entry.fullPath;下发出警报(imageURL);,如果@dfsq提到这是一个异步调用,那么当您在顶层访问它时,我相信您会发现imageURL是未定义的,因为回调还没有被调用

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

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

如果您使用的是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.
});

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