将未定义的方法承诺添加到稍后在 Promise.all() 中解析的数组
Add an undefined method promise to an array to be resolved later in Promise.all()
我想排队连接后执行的数据库调用。 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: Cannot read property 'then' of undefined
是否可以将一个未定义的方法,即 returns 一个承诺,添加到稍后在 Promise.all() 中解析的数组中?关于如何解决这个问题还有其他想法吗?
此外,我正在使用 Vue.js 和 PouchDB。
您可以在数据库模块中做出承诺,而不仅仅是 localDb
属性:
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()
,returns一个承诺。
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();
这里有一个 fiddle,其中包含一个允许方法参数的示例:https://jsfiddle.net/rjbv0284/1/
我想排队连接后执行的数据库调用。 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: Cannot read property 'then' of undefined
是否可以将一个未定义的方法,即 returns 一个承诺,添加到稍后在 Promise.all() 中解析的数组中?关于如何解决这个问题还有其他想法吗?
此外,我正在使用 Vue.js 和 PouchDB。
您可以在数据库模块中做出承诺,而不仅仅是 localDb
属性:
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()
,returns一个承诺。
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();
这里有一个 fiddle,其中包含一个允许方法参数的示例:https://jsfiddle.net/rjbv0284/1/