/* In this challenge you will test your knowledge of asynchronous functions. THE PROBLEMit: ATMs are very useful machines that give people access to their money when they need them without having to go inside a bank. Bank customers want a fast and reliable ATM experience. Let's consider at a high-level the operations that an ATM machine might perform for a simple cash withdrawal transaction. 1. Validate the customer's PIN 2. Validate that the customer has sufficient balance, if the pin is valid. 3. Update the customer's balance, if they have enough money to withdraw 4. Send notification e.g SMS to the user 5. Dispense the cash For most customers step 5 is probably what they care most about, so it will make sense to not to block on the notification operation which might take some time and instead dispense the money before the notification is sent. Asynchronous code can be very tricky to write and to understand. Synchronous code is straightforward to follow and understand because the operations are performed one after the other i.e sequentially. YOUR CHALLENGE: The withdraw function below depends on several asynchronous functions that are already provided for you. Your task is to update the withdraw function to ensure that the withdrawal logic executes correctly. Since all the functions are asynchronous, very bad things can happen if the order of execution is done correctly, e.g a person might be able to withdraw money even if their pin is wrong, or when the don't have enough balance. The bank is counting on your expertise to ensure that this doesn't happen!!! Good luck! */ let cashInMachine = 1000000 // Don't update this line async function withdraw (acctNum, amount, pin) { try { // Your task is to update the function calls below so that // they execute in the right order. // HINT: These functions are all asynchronous so by default don't wont block. // To wait for a function to be done, add await in front of it. await validatePin(acctNum, pin) await validateBalance(acctNum, amount) await updateBalance(acctNum, amount) notify(acctNum, amount) await dispenseCash(amount); return `Dispensed ${amount}. Machine balance: ${cashInMachine}` // Don't update this line. } catch (er) { return er; } } // STUDY THE CODE BELOW, BUT DON'T MODIFY THEM. const fakeDB = { 12345: { pin: 1111, balance: 2000 }, 45678: { pin: 2222, balance: 5000 }, 678910: { pin: 3333, balance: 5000 }, } // returns an acccount object if present in DB, otherwise throws an error async function getAccount(acctNum) { if(acctNum in fakeDB) { return fakeDB[acctNum] } else { throw 'account not found' } } // update account balance async function updateBalance(acctNum, amount) { return new Promise ((resolve) => { setTimeout(async function() { const account = await getAccount(acctNum); account.balance -= amount; resolve('done'); }, 150); }); } // throw an error if pin is incorrect async function validatePin (acctNum, pin) { if ((await getAccount(acctNum)).pin !== pin ) { throw 'invalid pin'; } } // throw an error if account balance is insufficient async function validateBalance (acctNum, amount) { if ( (await getAccount(acctNum)).balance < amount ) { throw 'insufficient balance'; } } // notify user of withdrawal and their current account balance async function notify(acctNum, amount) { return new Promise ((resolve) => { setTimeout(async function() { const acct = await getAccount(acctNum); console.log(`You withdrew ${amount}. Your current balance is ${acct.balance}`) resolve('notified') }, 100); }) } // disburse cash from machine async function dispenseCash(amount) { return new Promise ((resolve) => { setTimeout(async function() { cashInMachine -= amount; resolve('dispensed') }, 50); }); } // THIS IS HERE FOR YOUR TESTING ONLY async fucntion main(){ // *** PLEASE COMMENT OUT THE LINES BELOW BEFORE YOU SUBMIT *** // Shoud only print: // "Dispensed 500. Machine balance: 999500" // "You withdrew 500. Your current balance is 1500" console.log(await withdraw(12345, 500, 1111)) // comment out before submission // Should only print: // "invalid pin" // console.log(await withdraw(45678, 1000, 2221)) // comment out before submission }//main()
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter