我有一个函数(内部包含promise,因此它本身可以同步运行)似乎在我的主代码中异步运行。无论我如何格式化我的诺言,似乎在函数结束执行之前就已发送解决方法:
这个问题在逻辑上也是递归的,因为如果我尝试在nameExists函数周围添加另一个promise(在这个promise之内),然后将解决方案放在“ then”中,那么我只会遇到嵌套的解决方案...
document.getElementById("config-select").addEventListener("input", function(){
//check if the doc name exists: returns doc id
//promise that doc_obj is created before moving on
let doc_obj = {};
let promise = new Promise(function (resolve, reject) {
let doc_name = document.getElementById("config-select").value;
doc_obj = nameExists(doc_name);
resolve('done'); //this executes BEFORE nameExists is done processing...bringing back the original asynch issue i was trying to fix in the first place...
});
promise.then(function (result) {
alert("then: "+doc_obj);
if(doc_obj.bool === true){//it does exist:
alert("replacing id");
document.getElementById("config-select").setAttribute("doc-id", doc_obj.id);
}
else{//it doesn't:
alert("resetting id");
document.getElementById("config-select").setAttribute("doc-id", "");
}
}
);
});
nameExists函数:
//check if the name in config-select is an existing doc (assumes name is a unique document field)
const nameExists = function(name){
//get all docs
localDB.allDocs({include_docs: true}).then(function (result) {
//return object set to default state if no match is found
let doc_obj = {bool: false, id: ""};
alert("Entering the match checker...");
for(let i =0; i<result.total_rows; i++) {
if(result.rows[i].doc.name == name){
alert(result.rows[i].doc.name);
alert(name);
doc_obj.bool = true;
doc_obj.id = result.rows[i].doc._id;
//found a match
break;
}
}
//return the result
alert("returned obj.id: "+doc_obj.bool);
return doc_obj;
}).catch(function (err) {console.log(err);});
};
理想情况下,在评估“ if语句”之前,我希望使用nameExists函数中的数据填充doc_obj或某些返回值对象。我该如何格式化我的promise / resolve语句来实现这一目标?
答案 0 :(得分:1)
您应该删除该new Promise
-它不会改变您是否能够等待nameExists
的结果。您将需要return
在then()
函数内部创建的承诺:
nameExists
然后,您可以在事件监听器中等待它:
function nameExists(name) {
return localDB.allDocs({include_docs: true}).then(function (result) {
//^^^^^^
for (let i =0; i<result.total_rows; i++) {
if (result.rows[i].doc.name == name){
return {bool: true, id: result.rows[i].doc._id};
}
}
return {bool: false, id: ""};
});
// ^ don't catch errors here if you cannot handle them and provide a fallback result
}
答案 1 :(得分:0)
您仅有的一个异步调用位于nameExists函数内部,该函数是数据库调用,因此无需编写两个Promise,只需一个Promise就可以解决您的问题。
第一个事件应该是这样的:
document.getElementById("config-select").addEventListener("input", function(){
nameExists(doc_name).then(function(doc_obj) {
alert("then: "+doc_obj);
if(doc_obj.bool === true){//it does exist:
alert("replacing id");
document.getElementById("config-select").setAttribute("doc-id", doc_obj.id);
}
else{//it doesn't:
alert("resetting id");
document.getElementById("config-select").setAttribute("doc-id", "");
}
}).catch(function (err) { console.log(err) });
});
和nameExists函数应如下所示:
//check if the name in config-select is an existing doc (assumes name is a unique document field)
const nameExists = function(name){
//get all docs
return localDB.allDocs({include_docs: true}).then(function (result) {
//return object set to default state if no match is found
let doc_obj = {bool: false, id: ""};
alert("Entering the match checker...");
for(let i =0; i<result.total_rows; i++) {
if(result.rows[i].doc.name == name){
alert(result.rows[i].doc.name);
alert(name);
doc_obj.bool = true;
doc_obj.id = result.rows[i].doc._id;
//found a match
break;
}
}
//return the result
alert("returned obj.id: "+doc_obj.bool);
return(doc_obj); // here is where the code runs then statement inside the event
});
};