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()はグローバル変数app = {}内にあるため、app.downloadProductImage()からアクセスします。

この関数はループ内で実行され、imageURLを返したいのですが、取得できないようです。var app={}の外部でグローバルvar=imageURLを宣言しますが、別の関数でimageURLを取得しようとすると、最初のループはundefinedを返し、残りは正しいです。

最初のループが未定義を返す理由がわかりません。varimageURLはページの上部でグローバルに宣言されています。

上記のコード内で//RETURNTHIS imageURL = entry.fullPath;の下にalert(imageURL)を送信すると、関数の外部でアクセスしようとしたときではなく、正しくアラートが表示されます。

4

1 に答える 1

0

@dfsq がこれが非同期呼び出しであると述べたことを考えると、コールバックがまだ呼び出されていないため、トップレベルでアクセスすると imageURL が未定義であることがわかると思います。

これを確認する最も簡単な方法は、imageURL を設定する直前と直後に、コールバックに 2 つの console.log() ステートメントを挿入することです。もう 2 つの console.log() ステートメントは、imageURL にアクセスするトップレベル コードのポイント周辺にあります。

割り当ての前にアクセスが発生した場合は、「未定義」と表示される理由が説明されます。問題を解決するには、コールバックが終了するまで、トップレベルで行っていることを延期する必要があります。jQuery promise はこれを行う 1 つの方法ですが、他のライブラリにも他のオプションがあります。使用しているライブラリのキーワードとして「先物」、「約束」、「遅延実行」を探します。何らかのイベント フレームワークを使用している場合は、それを使用することもできます: コールバックでイベントをトリガーし、トップレベルでイベントをリッスンします (トリガーする前に必ずリッスンしてください。そうしないと、逆の問題が発生します)。

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 に答える