向未在Promise.all()中解析的数组添加未定义的方法承诺

问题描述 投票:0回答:2

我想排队一旦连接就会执行的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。

javascript asynchronous vue.js promise pouchdb
2个回答
0
投票

您可以在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())
)

0
投票

我解决了我的队列问题,但根本不是我试图去做的事情。

我的第一个问题是认为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/

© www.soinside.com 2019 - 2024. All rights reserved.