javascript - 如何避免javascript中的异步函数?
问题描述
function CanPurchase() {
return new Promise(function(resolve, reject){
var name = document.getElementById('name').value;
var civilNumber = document.getElementById('civilNumber').value;
var canPurchase_query = db.collection("observer").doc("purchase_record").collection("record_set").where("name",
"==", name).where("civilNumber", "==", civilNumber);
var result = "";
canPurchase_query
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
// doc.data() is never undefined for query doc snapshots
result += doc.data().time;
});
if (result) {
console.log("canPurchase", false);
alert(false);
resolve(false);
} else {
alert(true);
console.log("canPurchase", true);
resolve(true);
}
})
.catch(function (error) {
alert(false);
console.log("Error getting documents: ", error);
resolve(false);
});
});
}
function StoreBuyerListInDB() {
var serialNumber = document.getElementById("serialNumber3").value;
var name = document.getElementById("name").value;
var count = document.getElementById("count3").value;
var civilNumber = document.getElementById("civilNumber").value;
var canPurchase = CanPurchase().then(function(resolvedData){
return resolvedData;
});
sleep(3222);
//DB에 시리얼넘버, 이름, 개수, 주민번호 넣기
var docRef = db.collection("users").doc(firebaseEmailAuth.currentUser.uid);
var docRef2 = db.collection("users").doc(firebaseEmailAuth.currentUser.uid).collection("buyers");
var docRef3 = db.collection("observer").doc("purchase_record").collection("record_set");
//로그인된 사용자가 seller인지 확인
docRef.get().then(function (doc) {
if (doc.exists) {
if (doc.data().index != "seller") {
alert('seller가 아니라면 등록할 수 없습니다! 돌아가세요!');
return;
}
console.log("Document data:", doc.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
return;
}
}).catch(function (error) {
console.log("Error getting document:", error);
});
//어느 칸이라도 비어있으면 안됨
if (!serialNumber || !name || !count || !civilNumber) {
alert('제대로 입력해주세요!');
return;
}
//갯수가 0개이상 3개이해
else if (count < 0 || count >= 3) {
alert('1인당 3개 이하의 마스크만 구매 가능합니다! 다시 입력해주세요!');
return;
}
//주민번호 유효성
else if (!ValidateCivilNumber(civilNumber)) {
alert('주민번호가 유효하지 않습니다.');
return;
}
//전체 구매자 db에 이름, 주민번호가 같은사람이 있을경우 등록 불가
else if (!canPurchase) {
alert('이번주에 이미 구매하셨습니다.');
return;
}
else{
//해당seller의 db에 저장
docRef2.add({
name: name,
serialNumber: serialNumber,
count: count,
civilNumber: civilNumber,
time: firebase.firestore.FieldValue.serverTimestamp()
})
.then(function (docRef) {
console.log("Document written with ID: ", docRef.id);
alert("seller 저장 완료!");
setTimeout(GetDataFromDB(), 3000);
})
.catch(function (error) {
console.error("Error adding document: ", error);
alert("seller 저장 실패!");
});
//감사자인 observer db에 저장
docRef3.add({
name: name,
serialNumber: serialNumber,
count: count,
civilNumber: civilNumber,
time: firebase.firestore.FieldValue.serverTimestamp()
})
.then(function (docRef) {
console.log("Document written with ID: ", docRef.id);
alert("observer 저장 완료!");
setTimeout(GetDataFromDB(), 3000);
})
.catch(function (error) {
console.error("Error adding document: ", error);
alert("observer 저장 실패!");
});
}
}
我想知道用户可以通过使用 CanPurchase() 函数和 if 过程来购买物品。但在实际情况下,它不起作用。
else if (!canPurchase) {
alert('이번주에 이미 구매하셨습니다.');
return;
}
在这里它只是通过这个逻辑。所以无论 canPurchase 变量是什么,它都会继续。所以我搜索了一些方法来避免这个问题。我用了诺言。但它也不起作用。我该如何解决?太感谢了 !!
解决方案
无法使调用异步 API 的代码同步运行。如果您想与基于云的(以及大多数其他现代)API 进行交互,则必须学习使用异步调用。
在您的情况下,代码CanPurchase
可能会更简单一些,因为据我所知,您不需要声明自己的承诺。它应该是这样的:
function CanPurchase() {
var name = document.getElementById('name').value;
var civilNumber = document.getElementById('civilNumber').value;
var canPurchase_query = db.collection("observer").doc("purchase_record")
.collection("record_set")
.where("name", "==", name)
.where("civilNumber", "==", civilNumber);
var result = "";
return canPurchase_query
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
result += doc.data().time;
});
return !result
})
.catch(function (error) {
return false;
});
});
所以这不再有一个 custom Promise
,而是从内部返回值then
,catch
然后是查询。这是使用 Promise 时的常见模式,称为冒泡结果。
您现在可以使用以下命令调用此函数:
canPurchase().then(function(result) {
if(!result) {
alert('이번주에 이미 구매하셨습니다.');
}
}
如果您可以使用一些更现代的 JavaScript 功能,您可以使用async
/await
使这段代码看起来更熟悉一些:
async function CanPurchase() {
...
}
let result = await canPurchase();
if(!result) {
alert('이번주에 이미 구매하셨습니다.');
}
请记住,这是围绕带有承诺的现有流程的语法糖,并且不会改变这些是异步调用的事实。
推荐阅读
- recursion - 如果在列表中找不到数字,如何返回 false
- html - CSS 已加载但未应用
- laravel - 论坛模型如何引用论坛帖子?
- r - 如何将数量随机误差添加到 R 中的数值变量?
- c# - 在 Xamarin 应用程序中,我应该如何设置常量?
- node.js - 在 Windows 64bit 中安装Sharp时出错
- google-apps-script - 谷歌应用脚本,.getValue 返回错误
- go - Golang 字符串到 uint
- sql - 我需要搜索作者,他们的书名中有“计算机”一词,但不能有复数“计算机”
- python - 从熊猫数据框中的用户输入变量中获取上下N行