0

我有以下功能:

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 ,其余的都是正确的。

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

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

4

1 回答 1

0

鉴于@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.
});
于 2013-02-12T11:37:07.680 回答