我想排队连接后将执行的数据库调用。连接数据库对象后,它会创建并存储为模块的成员。
数据库模块:
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。
答案 0 :(得分:0)
您可以在db模块中做出承诺,而不仅仅是 import React, { Component } from 'react';
export class CheckboxRenderer extends Component{
constructor(props) {
super(props);
if(this.props.colDef.field==='noRestrictions'){
this.state={
value:true,
disable:false
};
}
else if(this.props.colDef.field==='doNotBuy')
{
this.state={
value:false,
disable:true
};
}
this.handleCheckboxChange=this.handleCheckboxChange.bind(this);
}
handleCheckboxChange(event) {
//this.props.data.checkbox=!this.props.data.checkbox; ={this.state.show}
//this.setState({value: this.props.data.checkbox});
if(this.state.value){this.setState({value: false});}
else{this.setState({value: true});}
alert(this.state.value);
//check for the last row and check for the columnname and enable the other columns
}
render() {
return (
<input type='checkbox' checked={this.state.value} disabled={this.state.disable} onChange={this.handleCheckboxChange}/>
);
}
}
export default CheckboxRenderer;
import React, { Component } from 'react';
import './App.css';
import { AgGridReact } from 'ag-grid-react';
import CheckboxRenderer from './CheckboxRenderer';
import 'ag-grid/dist/styles/ag-grid.css';
import 'ag-grid/dist/styles/ag-theme-balham.css';
class App extends Component {
constructor(props) {
super(props);
let enableOtherFields=false;
this.state = {
columnDefs: [
{headerName: 'Make', field: 'make'},
{headerName: 'noRestrictions', field: 'noRestrictions',
cellRendererFramework: CheckboxRenderer,
cellRendererParams:{checkedVal:true,disable:false},
onCellClicked: function (event) {
// event.node.columnApi.columnController.gridColumns[1].colDef.cellRendererParams.checkedVal=!event.node.columnApi.columnController.gridColumns[1].colDef.cellRendererParams.checkedVal;
// event.node.data.checkbox=!event.data.checkbox;
let currentNode=event.node.id;
event.api.forEachNode((node) => {
if(node.id===currentNode)
{
node.data.checkbox=!node.data.checkbox;
}
//if(!node.columnApi.columnController.gridColumns[1].colDef.cellRendererParams.checkedVal){ // checkbox is unchecked
if(node.data.checkbox===false && node.data.checkbox!=='undefined'){
enableOtherFields=true;
}
else
{
enableOtherFields=false;
}
//alert(node.id);
//alert(event.colDef.cellRendererParams.checkedVal);
}); alert("enable other fields:"+enableOtherFields);
}
},
{headerName:'doNotBuy',field:'doNotBuy',
cellRendererFramework: CheckboxRenderer,
cellRendererParams:{checkedVal:false,disable:true}
},
{headerName: 'Price', field: 'price', editable: true}
],
rowData: [
{make: "Toyota",noRestrictions:true,doNotBuy:false, price: 35000},
{make: "Ford", noRestrictions:true,doNotBuy:false,price: 32000},
{make: "Porsche", noRestrictions:true,doNotBuy:false, price: 72000}
]
};
}
componentDidMount() {
}
render() {
return (
<div
className="ag-theme-balham"
style={{height: '200px', width: '800px'}}
>
<AgGridReact
enableSorting={true}
enableFilter={true}
//pagination={true}
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}>
</AgGridReact>
</div>
);
}
}
export default App;
属性:
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()
答案 1 :(得分: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/