问题描述
这是我在香草javascript中的代码:
<html>
<Meta charset="utf-8"/>
<script src="//cdn.jsdelivr.net/npm/pouchdb@7.2.1/dist/pouchdb.min.js"></script>
<script src="https://unpkg.com/lunr/lunr.js"></script>
<script>
var dbp = new PouchDB('my_database');
var doc = {
"_id": "mittens","name": "Mittens","occupation": "kitten","age": 3,"hobbies": [
"playing with balls of yarn","chasing laser pointers","lookin' hella cute"
]
};
//db.put(doc);
dbp.put(doc);
var loaded = false;
var searchIndex;
dbp.allDocs({include_docs: true}).then((response) => {
searchIndex = lunr(function () {
this.ref("_id");
this.field("name",{boost: 10});
for (row in response.rows) {
temp = {
"name": response.rows[row].doc["name"],"_id": response.rows[row].doc["_id"]
};
this.add(temp);
}
});
console.log("finished");
loaded = true;
});
setTimeout(function () { //Beginning of code that should run AFTER the timeout
console.log("done");
result = searchIndex.search("mittens");
console.log(result[0]["ref"]);
//lots more code
},10000);
console.log(searchIndex.search("mittens"));
</script>
如果我等待10秒钟,搜索就会成功。我尝试在dbpouch搜索之前添加await,但是它不起作用。
如何使我的原始脚本等待dbpouch数据库的索引编制?
(index):59 Uncaught TypeError: Cannot read property 'search' of undefined
因为我的搜索尚未准备好。我想找到一种使脚本等待搜索索引完成的方法。
当我尝试等待db.put(doc);
https://jsfiddle.net/bussiere/4p1q3L9j/1/
我的主要目标是将dbpouch加载到月球上,然后可以进行多次搜索。
因此,只需要一次进行lunr搜索,而不是每次我都想进行搜索。
致谢
解决方法
您的代码有很大的问题
dbp.put(doc);
pouchDB的put
是异步的,因此代码与数据库不同步。
相反,
await dbp.put(doc);
或者如果您更喜欢基于Promise的方法,
dbp.put(doc).then((response) => {
// etc
});
下面的代码段基于您的代码,使用async / await。
更妙的是,在allDocs
或put
之后,bulkDocs
索引已准备就绪;但是对于二级索引(地图/缩小,芒果),不是正确。为了确保二级索引的完整结果,例如在大批量插入影响了map / reduce视图后,以下代码将等待二级索引完全建立。
await db.query(view_index,{ reduce: true });
要了解该技术的实际效果,请考虑使用this SO Q/A。
// Use memory adapter for testing to avoid having to deal with an existing database
const db = new PouchDB('my_database',{
adapter: 'memory'
});
// test doc
const doc = {
"_id": "mittens","name": "Mittens","occupation": "kitten","age": 3,"hobbies": [
"playing with balls of yarn","chasing laser pointers","lookin' hella cute"
]
};
// convenience
const gel = id => document.getElementById(id);
(async() => {
let header,result;
// ops
try {
// PUT is async.
await db.put(doc);
// allDocs index is ready. Not true for secondary indexes (map/reduce).
const response = await db.allDocs({
include_docs: true
});
// setup lunr
const searchIndex = lunr(function() {
this.ref("_id");
this.field("name",{
boost: 10
});
for (row in response.rows) {
temp = {
"name": response.rows[row].doc["name"],"_id": response.rows[row].doc["_id"]
};
this.add(temp);
}
});
// ok,search.
result = searchIndex.search("mittens");
header = "Search result";
} catch (err) {
// conflate error object and search result object.
result = [err];
header = "Error";
}
// display result
gel('header').innerText = header;
gel('result').innerText = JSON.stringify(result[0],undefined,3);
})();
.hide {
display: none
}
<html>
<meta charset="utf-8" />
<script src="//cdn.jsdelivr.net/npm/pouchdb@7.2.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.2.1/pouchdb.memory.min.js"></script>
<script src="https://unpkg.com/lunr/lunr.js"></script>
<body>
<div id='header'></div>
<pre id='result'></pre>
</body>
更新:这是一个基于Promise的代码段。 db和lunr初始化后,将出现一个搜索按钮。
// Use memory adapter for testing to avoid having to deal with an existing database
const db = new PouchDB('my_database',{
adapter: 'memory'
});
// lunr
var searchIndex;
var loaded = false; // true once index is ready.
// test doc
const doc = {
"_id": "mittens","lookin' hella cute"
]
};
// convenience
const gel = id => document.getElementById(id);
(() => {
// ops
return db.put(doc).then(function(response) {
// allDocs index is ready. Not true for secondary indexes (map/reduce).
return db.allDocs({
include_docs: true
});
// setup lunr
}).then(function(response) {
searchIndex = lunr(function() {
this.ref("_id");
this.field("name","_id": response.rows[row].doc["_id"]
};
this.add(temp);
}
});
loaded = true;
}).catch(function(err) {
// display init error.
gel('header').innerText = 'Error';
gel('result').innerText = JSON.stringify(err,3);
}).finally(function() {
// display search button on successful init.
if (loaded) {
// enable search button
gel('search').addEventListener('click',function() {
search();
});
gel('search').classList.remove('hide');
}
});
})();
// search function
function search() {
let header,result;
try {
result = searchIndex.search("mittens");
header = "Search result";
} catch (err) {
// conflate error object and search result object.
result = [err];
header = "Error";
}
gel('header').innerText = header;
gel('result').innerText = JSON.stringify(result[0],3);
}
.hide {
display: none
}
<html>
<meta charset="utf-8" />
<script src="//cdn.jsdelivr.net/npm/pouchdb@7.2.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.2.1/pouchdb.memory.min.js"></script>
<script src="https://unpkg.com/lunr/lunr.js"></script>
<body>
<button id='search' class='hide' style='margin-bottom: 1em'>
Search for 'mittens'
</button>
<div id='header'></div>
<pre id='result'></pre>
</body>