避免 js 中承诺冲突的最佳实践
Best practice to avoid clashing promises in js
我的应用程序中有一个可以手动调用的 save
函数和一个每 60 秒运行一次的 autosave
函数。
为了防止两个 ops 试图同时访问同一个文件,我将一个名为 isSaving
的标志设置为 true
,当一个开始时 运行,并设置为 false
之后再次。如果 open
或 save
检测到 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();
}
});
}
这感觉像是黑客攻击。有没有更好的方法来实现我想要做的事情?
仅供参考:这些函数 return promises 因为还有其他函数调用它们。
如何维护单个承诺链。然后,你可能不需要 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;
});
});
}
但我想,此代码的一个问题是,由于它是单一承诺链,您需要在应用程序中正确捕获错误。
与其等待 1000 毫秒再试,我建议使用 promise 来表示保存正在进行以及何时结束。
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
部分),尽管我看不出它如何干扰(自动)保存。如果您担心在保存文件时读取已经打开的文件,我会让文件系统处理并捕获错误。
我的应用程序中有一个可以手动调用的 save
函数和一个每 60 秒运行一次的 autosave
函数。
为了防止两个 ops 试图同时访问同一个文件,我将一个名为 isSaving
的标志设置为 true
,当一个开始时 运行,并设置为 false
之后再次。如果 open
或 save
检测到 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();
}
});
}
这感觉像是黑客攻击。有没有更好的方法来实现我想要做的事情?
仅供参考:这些函数 return promises 因为还有其他函数调用它们。
如何维护单个承诺链。然后,你可能不需要 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;
});
});
}
但我想,此代码的一个问题是,由于它是单一承诺链,您需要在应用程序中正确捕获错误。
与其等待 1000 毫秒再试,我建议使用 promise 来表示保存正在进行以及何时结束。
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
部分),尽管我看不出它如何干扰(自动)保存。如果您担心在保存文件时读取已经打开的文件,我会让文件系统处理并捕获错误。