Javascript 약속 파악
37488 단어 promisejavascript
무엇이 약속입니까?
promise는 비동기 실행 코드의 구조로 정해진 시간에 다음과 같은 상태 중 하나에 있을 수 있습니다.
미정: - 초기 상태, 만족도 거절도 하지 않습니다.
완료됨: - 성공적으로 실행되어
then
프로세서를 통해 값을 되돌려줍니다.거부: - 장애가 발생했습니다.
catch
프로세서 처리를 사용할 수 있습니다.return new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 1000);
})
위의 코드는 setTimeout
를 사용했는데, 이 예에서는 1초 동안의 값인'done'으로 약속을 해석합니다.다음promise를 사용하여 GitHub 사용자 정보를 얻는 코드를 고려하십시오.
function fetchUser(username) {
fetch('https://api.github.com/users/' + username)
.then(response => response.json())
.then( data => {
const str = JSON.stringify(data, undefined, 2);
document.getElementById('content').innerHTML = str;
})
.catch( error => console.error(error));
}
fetchUser('saroj990');
처음에 약속은 본 컴퓨터의javascript에 베이킹되지 않았고(es6는 본 컴퓨터의javascript에 구축될 것임) 제3자 라이브러리(예를 들어 Q
,BlueBird
를 통해 제공되었다.따라서 그 동안 개발된 모든 라이브러리는 전용 단독 프로미스 라이브러리를 사용하여 비동기성을 실현할 수 있다.어떻게 약속을 세웁니까?
우리는
Promise
수신 resolve
과 reject
을 매개 변수로 삼아 값을 되돌려 주려고 할 때 resolve
과 reject
를 사용하여 오류가 있는 약속을 거부할 수 있는 새로운 실례를 만들 수 있습니다.
function doAsync() {
return new Promise((resolve, reject) => {
const number = Math.ceil(Math.random() * 10);
if (number % 2 === 0) {
setTimeout(() => resolve("even"), 2000);
} else {
setTimeout(() => reject("odd"), 2000);
}
});
}
우리는 1에서 10 사이의 무작위 수를 계산하고 있다.만약 이 숫자가 짝수라면, 우리는 약속을 할 것이다.만약 가치가 홀수라면 우리는 약속을 거절할 것이다.다음은 우리가 약속을 어떻게 이행하는가이다.
doAsync()
.then((value) => {
// success handler
})
.catch(err => {
//log error
});
우리가 약속을 해석할 때 then
처리 프로그램은 이 값을 받을 것입니다. 거부하면 오류는 catch
처리 프로그램에 포착됩니다.우리는 왜 약속을 해야 합니까?
하면, 만약, 만약...👌👌. 하지만 나는 여기서 간단명료하게 유지할 것이다. 이렇게 하면 우리는 주제에서 벗어나지 않을 것이다.
약속의 제기는 지옥의 문제를 완화시키기 위한 것이다.
지옥으로 돌아가다
리셋은 매개 변수로 다른 함수에 전달될 수 있는 함수일 뿐이며, 더 많은 리셋이 다른 함수에 끼워져 있을 때 코드는 이해하기 어려워진다.
function getUser(id, profile, callback) {
User.find(id, function (err, user) {
if(err) {
callback(err);
} else {
user.profile = profile;
user.save(function(err, user) {
if(err) {
callback(err)
} else {
Subscription.findSubscription(id, function(err, subscription) {
if(err) {
callback(err) ;
} else {
user.subscription = subscription;
callback(subscription);
}
});
}
});
}
});
}
위의 코드는 보기에 매우 엉망이고 표현력이 전혀 없으며, 다른 플러그인 레벨이 나타날 때 상황은 더욱 나빠질 것이다.약속으로 같은 코드를 다시 생각해 봅시다.
function getUser(id, profile) {
const currentUser = {};
return new Promise((resolve, reject) => {
User
.find(id)
.then((user) => {
currentUser = user;
currentUser.profile = profile })
.then(() => Subscription.find(id))
.then(subscription => {
currentUser.subscription = subscription;
return resolve(currentUser)
})
.catch(err => reject(err))
})
}
지금 코드가 굉장히 깔끔해 보여요.👌👌. 안 그래?따라서 약속을 사용하는 것은 코드를 더 쉽게 읽을 수 있고 이해하기 쉽기 때문에 추가적인 장점이 있습니다.약속을 묶다
약속 체인은 하나의 약속의 출력이 다른 약속의 입력이 되는 모델이다.
다음은 우리가 예약을 시도한 예이다.
Appointment
.findSlot(time)
.then(slot => BookAnAppointment(slot.id))
.then(appointment => FinishPayment(appointment.id))
.then(payment => getInvoice(payment.id))
.then(invoice => console.log(invoice))
.catch(err => console.log(err));
평행 집행
어떤 경우 약속은 다른 약속과 무관하게 독립적으로 집행해야 한다.
Promise.all
promise에는 Javascript
구조가 있는데 이를 실현하기 위해 약속을 병행한다.// marks a user in-active
function markInActive(id) {
return User
.findById(id)
.then(user => {
user.active = false;
//returns a promise
return user.save();
});
}
// collect the promises into an array
const promises = []
for (let i=0; i < ids.length; i++) {
promises.push(markInActive(ids[i]));
}
//execute them altogether
Promise.all(promises)
.then(result => console.log(result))
.catch(error => console.log(error));
약속과 병행 실행을 연결하는 것이 어떤 차이가 있는지 알고 싶을 수도 있다.그래, 우리 하나의 예로 평가해 보자.
function promiseOne() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('promiseOne'), 1000);
})
}
function promiseTwo() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('promiseTwo'), 1000);
})
}
function promiseThree() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('promiseThree'), 1000);
})
}
약속이 체인에서 실행될 때 두 번째 약속은 첫 번째 약속이 완성될 때만 실행된다.promiseOne()
.then((res1) => {
console.log(res1);
return promiseTwo()
})
.then((res2) => {
console.log(res2);
return promiseThree();
}).then(res3 => {
console.log(res3);
})
.catch(err => console.log(err));
/*
output
promiseOne
promiseTwo
promiseThree
each promise takes 1sec to execute
effective time: 3sec
*/
현재, 우리는 Promise.all
를 사용하여 같은 코드를 시도하고, 모든 약속을 동시에 실행할 수 있도록 병행 실행을 허용합니다.
Promise.all([ promiseOne(), promiseTwo(), promiseThree()])
.then(result => console.log(result))
.catch(err => console.log(err));
/*
output:
[ 'promiseOne', 'promiseTwo', 'promiseThree' ]
all the promises get executed at the same time
so effective time: 1sec
*/
콜백을 약속으로 바꾸다
만약 당신이 이 점을 계속 따르고 있다면, 리셋을 약속으로 바꾸는 방법을 알아야 합니다.우선, 우리는 왜 우리가 약속을 되돌려야 하는지 알아야 한다.
일부 라이브러리 함수에promise variant 방법이 없을 때가 있습니다. (현재 거의 모든 라이브러리에promise 인터페이스 방법이 제공될 것 같습니다.) 그러나 약속으로 사용하기를 원합니다.
function saveUser(payload) {
return new Promise((resolve, reject) => {
User.save(payload, function(err, user) {
if(err) return reject(err);
return resolve(user);
});
});
}
User
모델save
방법은 리셋 방법입니다. 우리는 그것을 새로운 Promise
구조에 포장했을 뿐입니다. 리소스와reject가 포함되어 있습니다.오류가 발생하면 약속을 잘못 거절합니다. 그렇지 않으면 사용자 정보로만 해결할 것입니다.오류 처리 (캡처/최종)
약속을 만드는 것은 흥미롭지만, 약속을 실행할 때 발생할 수 있는 오류를 처리하지 않으면 아무 소용이 없습니다.이를 실현하기 위해서, 우리는
catch
처리 프로그램을 사용할 수 있으며, 오류 대상을 처리 프로그램 함수의 매개 변수로 수신할 수 있다.다음은catch 블록으로 처리된 오류 예시 코드입니다.
new Promise((resolve, reject) => {
reject("some error happened!");
}).catch(err => console.log(err));
우리도 약속에서 명확한 잘못을 던질 수 있다. 그것은 위와 완전히 같다.new Promise((resolve, reject) => {
throw new Error("some error occurred!!")
}).catch(err => console.log(err));
catch 프로세서는 프로그램 내에서 발생하는 동기화나 비동기화 이벤트를 처리할 수 있습니다.우리는 위의 예에서 우리가 고의로 잘못을 제기한 것을 보았다.이제 또 다른 잘못이 비동기적인 예임을 살펴봅시다.
const prom1 = () => new Promise((resolve, reject) => {
setTimeout(() => {
//rejects after 2sec
return reject("rejected prom1 promise");
}, 2000)
});
new Promise((resolve, reject) => resolve("done"))
.then(res => prom1())
.catch(err => console.log(err))
여기서 첫 번째 방법prom1
은 비동기적으로 약속을 거부한다(setTimeout만 모방했을 뿐)😉).then
와 catch
블록은 아래와 같이 하나씩 끼워 넣을 수 있다.
new Promise((resolve, reject) => {
resolve("done")
}).then(res => {
console.log("response is : ", res);
throw new Error("error after the first promise resolved"); // synchronous error
}).catch(err => {
console.log("error caught in catch handler", err);
return "You can rest now";
//simply pass the value to next level
}).then(res => console.log(res))
.catch(err => console.log(err));
// prints "you can rest now"
일반적으로, 사람들은 약속의 끝에 추가된catch 블록만 사용하는데, 발생하는 모든 오류는catch 처리 프로그램에 의해 포착된다.마침내
약속의 또 다른 중요한 부분은
finally
블록으로 약속이 성공하든 거절당하든 간에 모두 집행된다.
new Promise((resolve, reject) => resolve("done"))
.then(res => console.log(res))
.catch(err => console.log("I can catch fish too. :)"))
.finally(() => console.log("I am inevitable, I will always get a chance to execute"))
하나의 예로 더 잘 설명해 드리겠습니다. 그러면 우리는 finally
블록의 배후 원인을 진정으로 이해할 수 있습니다.isLoading = true;
fetchUser(id)
.then(user => subscribeToNewsLetter(user.id))
.then(response => {
console.log("subscribed to news letter", response);
// set loader to false once the user info is retrieved
isLoading = false;
})
.catch(err => {
console.log(err);
// in case of error
isLoading = false;
});
우리는 isLoading
변수를 사용하여 비동기 작업이 언제 시작되고, 언제 완성되는지 추적합니다. 그러면 응답을 받을 때 불러오는 프로그램을 표시하고 숨길 수 있습니다.말할 것도 없이 우리는 두 개의 다른 곳에서
isLoading
를 false
로 설정했다.then
내finally
블록으로 그것을 더욱 잘 처리할 수 있다.isLoading = true;
fetchUser(id)
.then(user => subscribeToNewsLetter(user.id))
.then(response => console.log("subscribed to news letter", response))
.catch(err => console.log(err))
.finally(() => isLoading = false);
Finally
블록은 실행될 것입니다. 약속한 대로 무슨 일이 발생하든지 간에 이것은 한 장소로서 정리와 닫기DB
, socket
연결 등을 할 수 있습니다.만약 네가 이미 이 점을 보충했다면, 축하해!!😁👍. 만약 이 글이 자바스크립트의 약속을 이해하는 데 도움이 된다고 생각한다면 망설이지 말고 이 글을 좋아해서 당신의 사랑을 표현하세요.
만약 글 중 일부 부분이 개선될 수 있다고 생각한다면, 평론을 추가하세요.고맙겠습니다.
Reference
이 문제에 관하여(Javascript 약속 파악), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/saroj990/mastering-javascript-promises-4kfh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)