在这里,我有一系列可靠的承诺。所有* .destroy都是返回承诺的承诺:
function callDBDestroy() {
var db;
DB_Categories.destroy().then(function () {
return DB_Equipment.destroy();
}).catch(function (err) {
showMsg("Error in callDBDestroy: " + err);
}).then(function () {
return DB_Certificates.destroy();
}).catch(function (err) {
showMsg("Error in callDBDestroy: " + err);
}).then(function () {
return DB_Locations.destroy();
}).catch(function (err) {
showMsg("Error in callDBDestroy: " + err);
});
}
但是我想在每一个中添加一个if语句来检查PouchDB数据库是否存在(如果DB_ *为null,它就不会这样做。)
如果它存在,我想要销毁它然后返回(这些都返回承诺)。
如果它不存在,我想返回一个匿名的诺言,它不返回任何内容,因为没有任何承诺有任何我关注的数据。
在这个例子中,我添加了一些示例代码来执行if语句,我想知道我会在null实例中放置什么来传递promise(resolve)值。
function callDBDestroy() {
var db;
DB_Categories.destroy().then(function () {
if( DB_Equipment != null) {
return DB_Equipment.destroy();
}
else {
Anonymous empty promise - something like:
new Promise().resolve();
}
}).then(function () {
return DB_Certificates.destroy();
}).then(function () {
return DB_Locations.destroy();
}).catch(function (err) {
showMsg("Error in callDBDestroy: " + err);
});
}
谢谢,
汤姆
答案 0 :(得分:1)
看起来你只是想知道如何手动解决/拒绝承诺。如果是这种情况,如果您想转到Promise.resolve(optionalValue)
处理程序,则可以致电Promise.reject(optionalValue)
或catch
:
function callDBDestroy() {
var db;
DB_Categories.destroy()
.then(function () {
if( DB_Equipment != null) {
return DB_Equipment.destroy();
} else {
return Promise.resolve();
}
}).then(function () {
return DB_Certificates.destroy();
}).then(function () {
return DB_Locations.destroy();
}).catch(function (err) {
showMsg("Error in callDBDestroy: " + err);
});
}
答案 1 :(得分:0)
你可以包装它:
function withDb(db, handler) {
return function onFulfilled(value) {
if(db === null) throw new Error("DB Null");
return handler(value);
});
}
可以让你这样做:
function callDBDestroy() {
var db;
var w = withDb(db); // or whatever instance
DB_Categories.destroy().then(w(function () {
// do stuff
}))); // .then(w( to chain calls here.
...
}
答案 2 :(得分:0)
我想返回一个匿名的承诺,它不会返回任何内容,因为没有任何承诺有任何我关心的数据。类似的东西:
new Promise().resolve();
您正在寻找Promise.resolve(undefined)
。虽然您可以省略undefined
,但这是隐含的。
….then(function () {
if (DB_Equipment != null) {
return DB_Equipment.destroy();
} else {
return Promise.resolve(undefined);
}
}).…
您甚至不必从then
回调中返回承诺,只需返回undefined
(或不return
)就会产生相同的效果。
….then(function () {
if (DB_Equipment != null) {
return DB_Equipment.destroy();
}
}).…
在您的情况下,我建议使用包装函数:
function destroyDatabase(db, name = "db") {
if (db != null)
return db.destroy().catch(err => {
showMsg(`Error in destroying ${name}: ${err}`);
});
else
return Promise.resolve();
}
function callDBDestroy() {
return destroyDatabase(DB_Categories, "categories")
.then(() => destroyDatabase(DB_Certificates, "certificates"))
.then(() => destroyDatabase(DB_Locations, "locations"))
}
// or even in parallel:
function callDBDestroy() {
return Promise.all([
destroyDatabase(DB_Categories, "categories"),
destroyDatabase(DB_Certificates, "certificates"),
destroyDatabase(DB_Locations, "locations")
]);
}
答案 3 :(得分:0)
如何使用数组,因为您执行相同的任务,只有数据库更改:
//serial
function callDBDestroy() {
var databases = [
DB_Categories,
DB_Equipment,
DB_Certificates,
DB_Locations
];
function errorMessage(err){ showMsg("Error in callDBDestroy: " + err) };
databases.reduce(
(prev, db) => db == null?
prev:
prev.then(() => db.destroy().catch(errorMessage)),
Promise.resolve()
)
}
//parallel
function callDBDestroy() {
var databases = [
DB_Categories,
DB_Equipment,
DB_Certificates,
DB_Locations
];
function errorMessage(err){ showMsg("Error in callDBDestroy: " + err) };
databases.forEach( db => db && db.destroy().catch(errorMessage) );
}
我添加了序列和并列版本。
答案 4 :(得分:0)
您似乎可以DRY使用数据库数组替换大量冗余代码,然后循环遍历数组:
function callDbDestroy();
var dbs = [DB_Categories, DB_Equipment, DB_Certificates, DB_Locations];
// chain all the destroys together
return dbs.reduce((p, db) => {
return p.then(() => {
if (db) {
return db.destroy().catch(err => {
showMsg("Error in callDBDestroy: " + err);
});
}
});
}, Promise.resolve());
}
您不必从.then()
处理程序返回承诺。如果你没有返回值,那就像做return undefined
一样,这意味着没有值会被传递给下一个.then()
处理程序,但是promise链会继续正常。从概念上讲,它与return Promise.resolve()
的工作方式相同,但没有必要在那里做出额外的承诺。
由于你没有将一个.then()
的值传递给链中的下一个,所以你没有任何东西可以通过那里,所以如果没有{{1调用destroy on的值。
仅供参考,使用db
循环数组是.reduce()
结构是一种常见的设计模式,用于对数组上的异步操作进行排序。
仅供参考,使用Bluebird promise库(有一些有用的帮助器),可以这样做:
return p.then(...)
有关Bluebird(或其他承诺库)即使使用ES6仍然有用的原因的详细信息,请参阅Are there still reasons to use promise libraries like Q or BlueBird now that we have ES6 promises?
由于看起来这些数据库可能都是独立的,我想知道为什么要强制它们按顺序执行。如果他们不必被迫按顺序进行,那么你可以这样做:
function callDbDestroy();
var dbs = [DB_Categories, DB_Equipment, DB_Certificates, DB_Locations];
return Promise.mapSeries(dbs, db => {
if (db) {
return db.destroy().catch(err => {
showMsg("Error in callDBDestroy: " + err);
});
}
});
}
由于这会并行运行操作,因此与严格的序列化相比,它有更快的端到端执行时间。