AngularJS 中的排序承诺

Sequencing promises in AngularJS

我正在尝试执行以下操作:

我这样做的方式是,复制文件部分在 promise 本身之前执行!所以它失败了,因为那里还没有目录!

代码: IMG_DIR_ENTRY是控制器内部的全局变量。

addImage

function addImage(imageURI) {
        return $q(function (resolve, reject) {

            handleImgDirCreation().then(function(imageDirEntry) {
                window.resolveLocalFileSystemURL(imageURI, function onResolveImgSuccess(imgFileEntry) {
                    imgFileEntry.copyTo(imageDirEntry, "img_" + + new Date(), function onCopySuccess(copiedImgFileEntry) {
                        images.push(copiedImgFileEntry.toURL());
                        window.localStorage.setItem(IMAGE_STORAGE_KEY, JSON.stringify(images));
                        resolve();
                    },
                    function onCopyFail(errMsgCopy) {
                        console.debug("ERROR: copy failed because: " + errMsgCopy);
                        reject();
                    });
                },
                function onResolveImgFail(errMsgResolveImg) {
                    console.debug("ERROR: couldn't resolve img because: " + errMsgResolveImg);
                    reject();
                });
            });
        });
    }


handleImgDirCreation(这不会在 .then() 之前被调用)

function handleImgDirCreation() {
        return $q(function(resolve, reject) {

            window.resolveLocalFileSystemURL(IMAGE_DIR, function onDirExists(imageDirEntry) {
                console.debug("SUCCESS: Directorio images ya existe.");
                resolve(imageDirEntry);
            },
            function onNonExistent(errMsgNonExistent) {
                createImageDirectory("WARNING: Directory didn't exist... || " + errMsgNonExistent);
                resolve(IMG_DIR_ENTRY);
            });
        });
    }


createImageDirectory

function createImageDirectory(errMsg) {
        console.debug(errMsg);
        console.debug("Creating IMG DIR --> " + IMAGE_DIR);

        window.resolveLocalFileSystemURL(DATA_DIRECTORY, function onResolveRootSuccess(rootDirEntry) {
            rootDirEntry.getDirectory('images', {create : true}, function onCreateDirSuccess(imgDirEntry) {
                console.debug("SUCCESS: Directory created --> " + imgDirEntry.toURL());
                IMG_DIR_ENTRY = imgDirEntry;
            },
            function onCreateDirFail(errMsgCreateDir) {
                console.debug("ERROR: Couldn't create image directory because: " + errMsgCreateDir);
            });
        },
        function onResolveRootFail(errMsgResolveRoot) {
            console.log("ERROR: Couldn't resolve root directory because: " + errMsgResolveRoot);
        });

    }

重要 我是用异步承诺来做的,否则 Android 的主线程(UI 线程)会过载和阻塞并跳过帧。也许还有另一种我不知道的方法。

要让代码等待目录创建,createImageDirectory 函数需要 return 一个承诺:

function createImageDirectory(errMsg) {
    var future = $q.defer();
    console.debug(errMsg);
    console.debug("Creating IMG DIR --> " + IMAGE_DIR);

    window.resolveLocalFileSystemURL(DATA_DIRECTORY, function onResolveRootSuccess(rootDirEntry) {
        rootDirEntry.getDirectory('images', {create : true}, function onCreateDirSuccess(imgDirEntry) {
            console.debug("SUCCESS: Directory created --> " + imgDirEntry.toURL());
            IMG_DIR_ENTRY = imgDirEntry;
            //RESOLVE with imgDirEntry;
            future.resolve(imgDirEntry);
        },
        function onCreateDirFail(errMsgCreateDir) {
            console.debug("ERROR: Couldn't create image directory because: " + errMsgCreateDir);
            //REJECT with error
            future.reject(errMsgCreateDir);
        });
    },
    function onResolveRootFail(errMsgResolveRoot) {
        console.log("ERROR: Couldn't resolve root directory because: " + errMsgResolveRoot);
        //REJECT with error
        future.reject(errMsgResolveRoot);
    });
    //RETURN promise
    return future.promise;

}

然后 handleImgDirCreation 函数需要使用该承诺进行解析:

function handleImgDirCreation() {
    return $q(function(resolve, reject) {

        window.resolveLocalFileSystemURL(IMAGE_DIR, function onDirExists(imageDirEntry) {
            console.debug("SUCCESS: Directorio images ya existe.");
            resolve(imageDirEntry);
        },
        function onNonExistent(errMsgNonExistent) {
            //createImageDirectory("WARNING: Directory didn't exist... || " + errMsgNonExistent);
            //resolve(IMG_DIR_ENTRY);
            var msg = "WARNING: Directory didn't exist... || " + errMsgNonExistent
            var directoryPromise = createImageDirectory(msg)
            //RESOLVE with directory promise
            resolve(directoryPromise);
        });
    });
}

通过使用目录创建承诺进行解析,从该承诺链接的后续方法将等待目录的创建。

Since a promise can be resolved with another promise (which will defer its resolution further), it is possible to pause/defer resolution of the promises at any point in the chain. This makes it possible to implement powerful APIs.

— AngularJS $q Service API Reference (Chaining Promises)