-
JAVASCRIPT PROMISESJava Script 2020. 8. 24. 17:43
https://www.youtube.com/watch?v=s1vpVCrT8f4
https://www.youtube.com/watch?v=JB_yU6Oe2eE&t=12s
1. Promise란
PROMISE 은 비동기 작업의 최종 결과를 나타내는 개체입니다.
Promise목적은 세 가지 상태 중 하나 일 수 있습니다 :
1. Pending : 초기 상태-작업이 아직 완료되지 않았습니다.
2. Fulfilled : 작업이 성공적으로 완료되었으며 이제 Promise에 해결 된 값이 있습니다.예를 들어 요청의 promise는 값으로 JSON 객체를 사용하여 확인할 수 있습니다.
3. Rejected : 작업이 실패했으며 프라 미스에 실패 이유가 있습니다. 이 이유는 대개 Error일종의 것입니다.
2. Constructing a Promise Object
Promise생성자 메소드 호출 함수 파라미터 얻어 집행 기능 생성자가 호출 될 때 자동으로 실행.
executor 함수는 일반적으로 비동기 작업을 시작하고 promise가 해결되어야하는 방법을 지정합니다.
executor 함수에는 일반적으로 resolve()및 reject()함수 라고하는 두 개의 함수 매개 변수가 있습니다.
resolve()및 reject()기능은 프로그래머에 의해 정의되지 않는다.
- resolve인수가 하나 인 함수입니다. 내부적으로 호출되면 프라 resolve() promise의 상태가 pending에서 fulfilled로 변경되고 프라미스의 해결 된 값은에 전달 된 인수로 설정됩니다 resolve().
- reject이유 또는 오류를 인수로 취하는 함수입니다. 내부적으로 호출되면 promise reject()의 상태가 pending에서rejected로 변경되고 프라미스의 거부 이유는에 전달 된 인수로 설정됩니다 reject().
const inventory = { sunglasses: 0, pants: 1088, bags: 1344 }; const myExecutor = (resolve, reject) => { if (inventory.sunglasses > 0) { resolve('Sunglasses order processed.'); } else { reject('That item is sold out.'); } } const orderSunglasses = () => { return new Promise (myExecutor); } const orderPromise = orderSunglasses(); console.log(orderPromise);
3. The Node setTimeout() Function
Promise를 구성하는 방법을 아는 것은 유용하지만 대부분의 경우
Promise를 소비 하거나 사용 하는 방법을 아는 것이 중요합니다.
정 시간이 지난 후 약속을 반환하는 함수를 제공하여이를 시뮬레이션 할 것입니다.
setTimeout()콜백 함수를 사용하여 지연 후 수행 할 작업을 예약하는
Node API (웹 브라우저에서 제공하는 유사한 API)입니다.
setTimeout()콜백 함수와 밀리 초 단위의 지연이라는 두 개의 매개 변수가 있습니다.
const delayedHello = () => { console.log('Hi! This is an asynchronous greeting!'); }; setTimeout(delayedHello, 2000);
여기서는 setTimeout()콜백 함수 delayedHello()와 2000.
최소 2 초 후에 delayedHello() 가 호출됩니다.
그러나 정확히 2 초가 아닌 "적어도"2 초인 이유는 무엇입니까?
이 지연은 비동기식으로 수행됩니다. 나머지 프로그램은 지연 중에 실행을 중지하지 않습니다.
비동기 자바 스크립트는 event-loop 라는 것을 사용 합니다 .
2 초 후 delayedHello()실행 대기중인 코드 줄에 추가됩니다.
실행되기 전에 프로그램의 모든 동기 코드가 실행됩니다.
다음으로 줄 앞의 모든 코드가 실행됩니다.
이는 delayedHello()실제로 실행 되기까지 2 초 이상 걸릴 수 있음을 의미합니다 .
setTimeout()비동기 프라 미스를 구성 하는 데 사용할 방법을 살펴 보겠습니다 .
const returnPromiseFunction = () => { return new Promise((resolve, reject) => { setTimeout(( ) => {resolve('I resolved!')}, 1000); }); }; const prom = returnPromiseFunction();
console.log("This is the first line of code in app.js."); const usingSTO = () => { console.log('Yay! Coding is so fun!!') } setTimeout(usingSTO, 3000); console.log("This is the last line of code in app.js."); /* $ node app.js This is the first line of code in app.js. This is the last line of code in app.js. Yay! Coding is so fun!! */
4. Consuming Promises
Promise 객체는 적절한 이름의 .then()메서드 와 함께 제공됩니다 .
그것은 우리가 말할 수 있습니다 "가 정착 할 때 내가 약속을 가지고, 다음, 여기에 내가 어떻게 할거야 ..."
우리의 식기 세척기 약속의 경우, 식기 세척기가 실행됩니다 다음 :
약속이 거부되면 접시가 더럽다는 뜻이며 비누를 추가하고 식기 세척기를 다시 작동 할 것입니다.
우리의 약속이 성취된다면 이것은 우리가 깨끗한 접시를 가지고 있다는 것을 의미하고 우리는 접시를 치울 것입니다.
.then()고차 함수입니다.두 개의 콜백 함수를 인수로 사용합니다. 이러한 콜백을 핸들러라고 합니다.
promise가 정산되면 정산 된 값으로 적절한 핸들러가 호출됩니다.
onFulfilled 라고도하는 첫 번째 핸들러 는 성공 핸들러 이며 promise 해결을 위한 로직을 포함해야합니다.
두 번째 핸들러 onRejected는 실패 핸들러( failure handler) 이며 promise 거절 에 대한 논리를 포함해야합니다..then()JavaScript Promise개체 의 메서드를 사용하여 비동기 작업의 최종 결과 (또는 오류)를 얻을 수 있습니다.
.then()두 개의 함수 인수를받습니다. 프로 미스가 해결되면 제공된 첫 번째 핸들러가 호출됩니다. 두 번째는 약속이 거부되면 호출됩니다.
const promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('Result'); }, 200); }); promise.then((res) => { console.log(res); }, (err) => { alert(err); });
5. onFulfilled 및 onRejected 함수
"성공"약속 또는 해결 된 약속을 처리하기 위해 우리 .then()는 약속에 대해 호출 하여 성공 핸들러 콜백 함수를 전달합니다.
const prom = new Promise((resolve, reject) => { resolve('Yay!'); }); const handleSuccess = (resolvedValue) => { console.log(resolvedValue); }; prom.then(handleSuccess); // Prints: 'Yay!'
let prom = new Promise((resolve, reject) => { let num = Math.random(); if (num < .5 ){ resolve('Yay!'); } else { reject('Ohhh noooo!'); } }); const handleSuccess = (resolvedValue) => { console.log(resolvedValue); }; const handleFailure = (rejectionReason) => { console.log(rejectionReason); }; prom.then(handleSuccess, handleFailure);
6. catch ()
promise 객체 의 메서드에 두 번째 인수로 전달 된 함수 는 promise .then()가 거부 될 때 사용됩니다.
이 접근 방식의 대안 .catch()은 promise 개체 의 JavaScript 메서드 를 사용하는 것입니다.
거부에 대한 정보는 .catch()메소드에 제공된 핸들러에서 사용할 수 있습니다 .
const promise = new Promise((resolve, reject) => { setTimeout(() => { reject(Error('Promise Rejected Unconditionally.')); }, 1000); }); promise.then((res) => { console.log(value); }); promise.catch((err) => { alert(err); });
7. Chaining Multiple Promises
우리는 데이터베이스에 하나의 요청을하고 우리에게 반환 된 데이터를 사용하여 또 다른 요청을 할 수 있습니다!
다른 청소 예인 빨래를 예로 들어 설명하겠습니다.
우리는 더러운 옷을 가져다가 세탁기에 넣습니다. 옷을 청소하는 경우, 다음 우리는 건조기에 넣고 싶을 것이다.건조기 실행 한 후, 옷을 건조하는 경우, 그 다음 우리는 그들을 바구니에 넣을 수 있습니다.
약속을 함께 연결하는이 과정을 composition 이라고 합니다. 약속은 구도를 염두에두고 설계되었습니다!firstPromiseFunction() .then((firstResolveVal) => { return secondPromiseFunction(firstResolveVal); }) .then((secondResolveVal) => { console.log(secondResolveVal); });
- 우리 firstPromiseFunction()는 promise를 반환 하는 함수 를 호출합니다 .
- .then()익명 함수를 성공 핸들러로 호출 합니다.
- 성공 핸들러 내에서 우리 는 새로운 약속 을 반환secondPromiseFunction() 합니다. 첫 번째 약속의 해결 된 값 으로 두 번째 함수를 호출 한 결과입니다 .
- .then()두 번째 약속 정착에 대한 논리를 처리하기 위해 두 번째 를 호출합니다 .
- 그 안에는 .then()두 번째 promise의 해결 된 값을 콘솔에 기록하는 성공 핸들러가 있습니다.
// library.js const store = { sunglasses: { inventory: 817, cost: 9.99 }, pants: { inventory: 236, cost: 7.99 }, bags: { inventory: 17, cost: 12.99 } }; const checkInventory = (order) => { return new Promise ((resolve, reject) => { setTimeout(()=> { const itemsArr = order.items; let inStock = itemsArr.every(item => store[item[0]].inventory >= item[1]); if (inStock){ let total = 0; itemsArr.forEach(item => { total += item[1] * store[item[0]].cost }); console.log(`All of the items are in stock. The total cost of the order is ${total}.`); resolve([order, total]); } else { reject(`The order could not be completed because some items are sold out.`); } }, generateRandomDelay()); }); }; const processPayment = (responseArray) => { const order = responseArray[0]; const total = responseArray[1]; return new Promise ((resolve, reject) => { setTimeout(()=> { let hasEnoughMoney = order.giftcardBalance >= total; // For simplicity we've omited a lot of functionality // If we were making more realistic code, we would want to update the giftcardBalance and the inventory if (hasEnoughMoney) { console.log(`Payment processed with giftcard. Generating shipping label.`); let trackingNum = generateTrackingNumber(); resolve([order, trackingNum]); } else { reject(`Cannot process order: giftcard balance was insufficient.`); } }, generateRandomDelay()); }); }; const shipOrder = (responseArray) => { const order = responseArray[0]; const trackingNum = responseArray[1]; return new Promise ((resolve, reject) => { setTimeout(()=> { resolve(`The order has been shipped. The tracking number is: ${trackingNum}.`); }, generateRandomDelay()); }); }; // This function generates a random number to serve as a "tracking number" on the shipping label. In real life this wouldn't be a random number function generateTrackingNumber() { return Math.floor(Math.random() * 1000000); } // This function generates a random number to serve as delay in a setTimeout() since real asynchrnous operations take variable amounts of time function generateRandomDelay() { return Math.floor(Math.random() * 2000); } module.exports = {checkInventory, processPayment, shipOrder};
//app.js const {checkInventory, processPayment, shipOrder} = require('./library.js'); const order = { items: [['sunglasses', 1], ['bags', 2]], giftcardBalance: 79.82 }; checkInventory(order) .then((resolvedValueArray) => { return processPayment(resolvedValueArray) }) .then((resolvedValueArray) => { return shipOrder(resolvedValueArray) }) .then((successMessage) => { console.log(successMessage); }) .catch((errorMessage) => { console.log(errorMessage); }); /* $ node app.js All of the items are in stock. The total cost of the order is 35.97. Payment processed with giftcard. Generating shipping label. The order has been shipped. The tracking number is: 24916. */
8. Avoiding Common Mistakes
두 가지 일반적인 실수를 살펴 보겠습니다.
실수 1 : 약속을 연결하는 대신 중첩합니다..
returnsFirstPromise() .then((firstResolveVal) => { return returnsSecondValue(firstResolveVal) .then((secondResolveVal) => { console.log(secondResolveVal); }) })
실수 2 :return 약속을 잊어 버림 .
returnsFirstPromise() .then((firstResolveVal) => { returnsSecondValue(firstResolveVal) }) .then((someVal) => { console.log(someVal); })
9. Promise.all()
promise 구성은 비동기 작업이 서로 의존하거나 실행 순서가 중요한 상황을 처리하는 좋은 방법입니다.
하지만, 여러 약속을 처리하고 있지만 순서에 신경 쓰지 않으면 어떻게됩니까?
집이 깨끗하다고 생각하려면 옷을 말리고 쓰레기통을 비우고 식기 세척기를 가동해야합니다.
또한 모든 작업이 비동기 적으로 수행되기 때문에 실제로 모두 동시에 발생해야합니다!
효율성을 극대화하려면 동시성 을 사용해야 합니다 .
여러 비동기 작업이 함께 발생합니다.
Promise.all() 를 사용하면 함수로 이를 수행 할 수 있습니다
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve(3); }, 300); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve(2); }, 200); }); Promise.all([promise1, promise2]).then((res) => { console.log(res[0]); console.log(res[1]); });
'Java Script' 카테고리의 다른 글
Requests II (fetch) (0) 2020.09.01 ASYNC AWAIT (0) 2020.08.26 WorkAround (0) 2020.08.19 Message Mixer (0) 2020.08.18 Modules (0) 2020.08.13