ES7 에서 Await 를 이용 하여 리 셋 을 줄 이 는 방법 에 대한 상세 한 설명
우 리 는 자바 script 이 막 을 수 없다 는 것 을 알 고 있 습 니 다.모든 기다 림 은 리 셋 을 통 해 만 이 루어 질 수 있 습 니 다.이 로 인해 리 셋 끼 워 넣 는 문제 가 발생 하여 코드 가 폭발 할 때 Await 는 쓸모 가 있 습 니 다.
await 의 밑바닥 메커니즘 에 대해 여기 서 상세 하 게 설명 하지 않 겠 습 니 다.문장의 편폭 을 길 게 끌 지 않도록 필요 한 친구 들 은 이 글 을 참고 할 수 있 습 니 다https://www.jb51.net/article/123257.htm다음은 본 고의 정식 내용 을 시작 하 겠 습 니 다.
Await 를 이용 하여 리 셋 을 감소 합 니 다.
우리 모 두 는 개발 할 때,때때로 많은 요 구 를 보 내야 한다.그리고 종종 플러그 인 리 셋 문제 에 직면 하 게 된다.즉,리 셋 안에 리 셋 이 하나 더 박 혀 있어 서 코드 가 겹겹이 들 어가 게 된다.
다음 코드 와 같이:
ajax({
url: "/list",
type: "GET",
success: function(data) {
appendToDOM(data);
ajax({
url: "/update",
type: "POST",
success: function(data) {
util.toast("Success!");
})
});
}
});
이런 코드 는 보기에 좀 힘 들 어 보인다.이런 비동기 리 셋 은 보통 Promise 로 최적화 할 수 있 고 위의 코드 를 다음 과 같이 바 꿀 수 있다.
new Promise(resolve => {
ajax({
url: "/list",
type: "GET",
success: data => resolve(data);
})
}).then(data => {
appendToDOM(data);
ajax({
url: "/update",
type: "POST",
success: function(data) {
util.toast("Successfully!");
})
});
});
Promise 는 resolve 를 제공 하여 언제 비동기 가 끝 났 는 지 알 릴 수 있 습 니 다.그러나 본질 은 똑 같 습 니 다.리 셋 을 사용 합 니 다.다만 이 리 셋 은 then 에 넣 었 습 니 다.비동기 데 이 터 를 여러 번 가 져 와 야 할 때 Promise.all 로 해결 할 수 있 습 니 다.
let orderPromise = new Promise(resolve => {
ajax("/order", "GET", data => resolve(data));
});
let userPromise = new Promise(resolve => {
ajax("/user", "GET", data => resolve(data));
});
Promise.all([orderPromise, userPromise]).then(values => {
let order = values[0],
user = values[1];
});
그런데 여기 도 리 턴 을 사 용 했 는데 우아 한 해결 방법 이 있 나 요?ES7 의 await/async 는 동기 화 코드 를 쓰 는 것 과 같은 비동기 적 인 쓰기 방법 을 사용 할 수 있 습 니 다.첫 번 째 플러그 인 리 셋 의 예 는 await 로 다음 코드 로 바 꿀 수 있 습 니 다.
// await
let leadList = await new Promise(resolve => {
ajax({
url: "/list",
type: "GET",
success: data => resolve(data);
});
});
// await
appendToDom(leadList);
ajax({
url: "/update",
type: "POST",
success: () => util.toast("Successfully");
});
Await 는 코드 를 폭포 흐름 처럼 자 연 스 럽 게 쓸 수 있 도록 합 니 다.두 번 째 예:여러 번 비동기 데 이 터 를 가 져 오 면 이렇게 바 꿀 수 있 습 니 다.
let order = await new Promise(
resolve => ajax("/order", data => resovle(data))),
user = await new Promise(
resolve => ajax("/user", data => resolve(data)));
// do sth. with order/user
이런 쓰 기 는 마치 현지에서 데 이 터 를 얻 는 것 처럼 리 셋 함 수 를 끼 워 넣 지 않 아 도 된다.Await 는 요청 을 보 내 는 것 외 에 다른 비동기 장면 에 도 사용 할 수 있 습 니 다.예 를 들 어 제 가 주문 서 를 만 들 기 전에 작은 상 자 를 쳐 서 사용자 에 게 어떤 유형의 주문 서 를 만 들 려 고 하 는 지 물 어 본 다음 에 구체 적 으로 주문 서 를 설정 하 는 상 자 를 쳐 야 합 니 다.그래서 정상 적 인 생각 에 따라 버튼 을 누 르 고 리 셋 하 는 클릭 함 수 를 전달 해 야 합 니 다.다음 그림 과 같 습 니 다.
그러나 사실은 await 로 해결 할 수 있 습 니 다.다음 코드 와 같 습 니 다.
let quoteHandler = require("./quote");
//
let createType = await quoteHandler.confirmCreate();
quote 에서 Promise 를 되 돌려 주 고 클릭 이 벤트 를 감청 하 며 createType 을 전달 합 니 다.
let quoteHandler = {
confirmCreate: function(){
dialog.showDialog({
contentTpl: tpl,
className: "confirm-create-quote"
});
let $quoteDialog = $(".confirm-create-quote form")[0];
return new Promise(resolve => {
$(form.submit).on("click", function(event){
resolve(form.createType.value);
});
});
}
}
이렇게 하면 외부 호출 자 는 클릭 이벤트 의 반전 함 수 를 전달 하지 않 고 await 를 사용 할 수 있 습 니 다.하지만 주의해 야 할 것 은 await 의 일회 성 실행 특징 이다.리 셋 함수 에 비해 await 의 실행 은 일회 성 입 니 다.예 를 들 어 클릭 이 벤트 를 감청 한 다음 에 await 를 사용 하면 이 벤트 를 클릭 하면 한 번 만 실 행 됩 니 다.코드 가 위 에서 아래로 실행 되 었 기 때문에 클릭 후에 오류 가 발생 하면 계속 수정 하고 제출 할 수 있 으 면 await 를 사용 할 수 없습니다.또한 await 를 사용 하여 비동기 데 이 터 를 가 져 옵 니 다.오류 가 발생 하면...그러면 성공 적 인 resolve 는 실행 되 지 않 고 후속 코드 도 실행 되 지 않 기 때문에 요청 이 잘못 되 었 을 때 기본 논리 에 문제 가 없 을 것 입 니 다.
babel 에서 await 를 사용 하려 면:
(1)노드 패키지 설치
npm install --save-dev babel-plugin-transform-async-to-generator
(2)프로젝트 의 루트 디 렉 터 리 에'babelrc 파일'을 추가 합 니 다.내용 은:
{
"plugins": ["transform-async-to-generator"]
}
(3)사용 할 때 모듈 을 먼저 도입 한다.
require("babel-polyfill");
그리고 ES7 의 await 를 즐겁게 사용 할 수 있 습 니 다.await 함수 앞 에 async 키 워드 를 추가 해 야 합 니 다.다음 코드:
async showOrderDialog() {
//
let createType = await quoteHandler.confirmCreate();
//
let orderInfo = await orderHandler.getOrderData();
}
우 리 는 다시 하나의 예 를 들 어 await 를 사용 하여 JS 판 sleep 함 수 를 실현 합 니 다.원생 은 스 레 드 휴면 함 수 를 제공 하지 않 았 기 때문에 다음 코드 와 같 습 니 다.
function sleep (time) {
return new Promise(resolve =>
setTimeout(() => resolve(), time));
}
async function start () {
await sleep(1000);
}
start();
babel 의 await 실현 은 ES6 의 generator 로 바 뀌 었 습 니 다.다음 과 같은 핵심 코드 입 니 다.
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
// sleep Promise
return sleep(1000);
case 2:
case "end":
return _context.stop();
}
}
그리고 babel 의 generator 도 ES5 로 이 루어 져 야 합 니 다.generator 는 무엇 입 니까?다음 그림 에서 보 듯 이:생 성 기 는 function*로 정의 합 니 다.생 성기 의 next 함 수 를 실행 할 때마다 현재 생 성기 에서 yield 로 돌아 온 값 을 되 돌려 줍 니 다.그리고 생 성기 의 교체 기 는 모든 yield 가 끝 날 때 까지 한 걸음 뒤로 갑 니 다.
관심 있 는 것 은 babel 이 어떻게 ES7 을 ES5 로 바 꾸 었 는 지 계속 연구 할 수 있 습 니 다.원생 의 실현 이 냐,아니면 Promise 에 기초 한 것 이 냐 고 합 니 다.
await 를 사용 하면 또 하나의 장점 이 있 습 니 다.try-catch 는 비동기 과정 에서 던 진 이상 을 직접 포착 할 수 있 습 니 다.왜냐하면 우 리 는 비동기 반전 안의 이상 을 직접 포착 할 수 없 기 때 문 입 니 다.다음 코드:
let quoteHandler = {
confirmCreate: function(){
$(form.submit).on("click", function(event){
// undefined : undefined value
callback(form.notFoundInput.value);
});
}
}
try {
//
quoteHandler.confirmCreate();
} catch (e) {
}
위의 try-catch 는 이상 을 포착 할 수 없습니다.try 의 코드 가 실행 되 었 기 때문에 실행 과정 에서 이상 이 없 기 때문에 여기 서 잡 을 수 없습니다.Promise 를 사용 하면 Promise 체인 의 catch 를 사용 합 니 다.
let quoteHandler = {
confirmCreate: function(){
return new Promise(resolve => {
$(form.submit).on("click", function(event){
// undefined : undefined value
resolve(form.notFoundInput.value);
});
});
}
}
quoteHandler.confirmCreate().then(createType => {
}).catch(e => {
//
});
await 를 사용 하면 우 리 는 동기 화 된 catch 를 직접 사용 할 수 있 습 니 다.마치 그것 이 동기 화 된 것 같 습 니 다.
try {
createType = await quoteHandler.confirmCreate("order");
}catch(e){
console.log(e);
return;
}
한 마디 로 하면 await 를 사용 하여 코드 에 많은 끼 워 넣 기 를 적 게 쓰 고 편리 한 논리 적 처리 로 부 드 러 움 을 누 릴 수 있 습 니 다.총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.