简体   繁体   中英

How to avoid async functions in 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 저장 실패!");
          });
        }
    }

I wanna know user can purchase items or not by using CanPurchase() function and if process. But in real case, it doesn't work.

 else if (!canPurchase) {
        alert('이번주에 이미 구매하셨습니다.');
        return;
      }

here it just pass this logic. so whatever canPurchase variable is, it just go on. So I searched some ways to avoid this problem. I used promise. but also it doesn't work too. How can i solve it? Thank you so much !!

There is no way to make code that calls an asynchronous API behave synchronously. If you want to interact with cloud-based (and most other modern) APIs, you will have to learn to work with asynchronous calls.

In your case, the code for CanPurchase can be a bit simpler, as you don't need to declare your own promise as far as I can see. It should be something like this:

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;
    });
});

So this no longer has a custom Promise , but instead returns the value from within then and catch and then the query. This is a common pattern when using promises, and is called bubbling up the results.

You can now call this function with:

canPurchase().then(function(result) {
  if(!result) {
    alert('이번주에 이미 구매하셨습니다.');
  }
}

If you're OK with using some more modern JavaScript feature, you can use async / await to make this code look a bit more familiar:

async function CanPurchase() {
  ...
}

let result = await canPurchase();
if(!result) {
  alert('이번주에 이미 구매하셨습니다.');
}

Just keep in mind that this is syntactic sugar around the existing flow with promises, and does not change the fact that these are asynchronous calls.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM