避免在js中冲突承诺的最佳做法

时间:2015-09-02 09:20:11

标签: javascript promise winjs

我的app中有一个save函数,可以手动调用,autosave函数每隔60秒运行一次。

为了防止两个操作系统在同一时刻尝试访问同一个文件,我在开始运行时将isSaving设置为true,然后再设置为false。如果opensave检测到autosave正在运行,则会等待1000毫秒并重试。如果他们在那之后失败了,我认为这是一个错误。

自动保存:

setInterval(autosave, 1000 * 60);
isSaving = false;

function autosave() 
{        
    return new WinJS.Promise(function (complete, error, progress) 
    {
        if(isSaving == false) // no saving op in progress
        {
            // set saving flag on
            isSaving = true;
            // write file
            return writeFile(currentFile)
                .then(function () {
                    // saving flag off
                    isSaving = false;
                    complete();
                });
        }    
        else {
            // silently abort
            complete();
        }        
    });
}

手动保存:

var saveFileAttempts = 0;
function save()
{
    return new WinJS.Promise(function (complete, error, progress)
    {
        if (isSaving == false) // no saving op in progress
        {
            // set saving flag on
            isSaving = true;
            // write file
            return writeFile(currentFile)
                .then(function () {
                    // show notification to user "file saved"
                    return showSaveNotification()
                })
                .then(function () {
                    // set saving flag off
                    isSaving = false;
                    complete();
                });
        }
        else if (saveFileAttempts < 10) { 
            // try again in 1000ms, up to 10 times
            saveFileAttempts++;
            setTimeout(function () { save(); }, 1000);
        }
        else{
            error();
        }
    });
}

打开:

var openFileAttempts = 0;
function open()
{
    return new WinJS.Promise(function (complete, error, progress)
    {
        if (isSaving == false)
        {
            return readFile()
                .then(function (file) {
                    currentFile = file;
                    openFileAttempts = 0;
                    complete();
                });
        }
        else if (openFileAttempts < 10) { 
            // try again in 1000ms, up to 10 times
            openFileAttempts++;
            setTimeout(function () { open(); }, 1000);
        }
        else{
            error();
        }
    });
}

这感觉就像一个黑客。有没有更好的方法来实现我想要做的事情?

仅供参考:这些函数返回promises,因为还有其他函数可以调用它们。

2 个答案:

答案 0 :(得分:0)

如何维护单一的承诺链。那么,你可能不需要setTimeout,这是一个简单的方法,可能有缺陷,没有使用WinJS,编写代码就像是正常的承诺:

setInterval(save, 1000 * 60);
var promise = Promise.resolve(); 



function save(){
    return promise.then(function(){
        return writeFile(currentFile);
    });
}

function open(){
    return promise.then(function(){
        return readFile().then(function (file) {                
            currentFile = file;
        });
    });
}

但我想,这段代码的一个问题是,因为它是单一的承诺链,你需要在应用程序中正确捕获错误。

答案 1 :(得分:0)

我没有等待1000毫秒再次尝试,而是建议使用承诺来表示保存正在进行以及何时结束。

var saving = null;

setInterval(function() {
    if (!saving) // ignore autosave when already triggered
        save().then(showAutoSafeNotification);
}, 60e3);

function save() {
    if (saving)
        return saving.then(save); // queue
    // else
    var written = writeFile(currentFile);
    saving = written.then(function() {
        saving = null;
    }, function() {
        saving = null;
    });
    return written;
}

您可以对open执行相同的操作(并且可能希望将written部分抽象出来),尽管我无法看到它如何干扰(自动)保存。如果您担心在保存文件时读取已经打开的文件,我会让文件系统处理它并捕获错误。