我想排队一旦连接就会执行的DB调用。 DB对象在连接时创建并存储为模块的成员。
数据库模块:
var db = {
localDb: null,
connectLocal: (dbName) => {
// Do stuff
this.localDb = new PouchDB(dbName) // has a allDocs() method
}
}
添加对队列的调用:
var dbQueue = []
function getDocs () {
dbQueue.push (
db.localDb.allDocs () // allDocs() not yet defined; returns promise
)
}
// Called when connected and queue is not empty:
function processQueue () {
Promise.all (dbQueue)
.then(...)
}
如果在db.connectLocal()设置db.localDb之前调用getDocs(),则会出现以下错误(或类似错误),因为尚未定义db.localDb:
TypeError:无法读取未定义的属性'then'
是否有可能将一个未定义的方法(将返回一个promise)添加到稍后在Promise.all()中解析的数组中?关于如何解决这个问题的任何其他想法?
另外,我正在使用Vue.js和PouchDB。
您可以在db模块中而不仅仅是localDb
属性中创建一个promise:
let localDb = null;
let resolveLocalDb = null;
let localDbPromise = new Promise(function(resolve, reject) {
resolveLocalDb = resolve;
});
var db = {
getLocalDb: () {
return localDbPromise;
}
connectLocal: (dbName) => {
// Do stuff
localDb = new PouchDB(dbName) // has a allDocs() method
resolveLocalDb(localDb);
}
}
然后,将.localDb
交换给getLocalDb()
,后者返回一个承诺。
dbQueue.push(
db.getLocalDb().then(db => db.allDocs())
)
我解决了我的队列问题,但根本不是我试图去做的事情。
我的第一个问题是认为Promise.all()延迟调用我的方法直到它被调用,但是在添加到数组时会调用它们。这导致我在我的问题中提到的错误。所以我需要重新思考如何使用可能尚不存在的方法填充队列。
解决方案是将对数组(队列)的调用添加为字符串(例如"getDocs"
),然后使用bracket notation(例如db["getDocs"]()
)遍历调用方法的数组。
我的应用程序是用Vue.js编写的,所以它显然是不同的,但这是一个简化的工作示例:
// Dummy DB object
var db = {
docs: [1, 2, 3]
};
// Queue were the DB ops are stored
var dbQueue = [];
// Process the queue - called elsewhere once the DB is connected
// The processed array and Promise.all() aren't necessary as you could just call
// the method outright, but I want to log the results in order
async function processQueue() {
var processed = []; // Called queue methods
// Add valid methods to
dbQueue.forEach(method => {
if (typeof db[method] === "function") {
return processed.push(db[method]());
} else {
console.error(`"${method}" is not a name of a valid method.`);
}
});
// Log promise results
await Promise.all(processed).then(res => {
console.log("Processed:", res);
});
// Empty the queue
dbQueue = [];
}
// Add some calls to the queue of methods that don't yet exist
dbQueue.push("getDocs");
dbQueue.push("getDocs");
// Simulate adding the method
db.getDocs = function() {
return new Promise(resolve => {
resolve(this.docs);
});
};
// Process queue once conditions are met (e.g. db is connected); called elsewhere
processQueue();
这里有一个例子,允许方法的参数:https://jsfiddle.net/rjbv0284/1/