자바 스크립트 — 콜백에서 비동기 / 대기

자바 스크립트는 동기식입니다. 즉, 권상 후 순서대로 코드 블록을 실행합니다. 코드가 실행되기 전에 var function 선언은 해당 범위의 맨 위로 “게재”됩니다.

다음은 동기 코드의 예입니다.

이 코드는 “1 2 3″을 안정적으로 기록합니다.

비동기 요청은 나머지 코드가 계속 실행되는 동안 타이머가 완료되거나 요청이 응답 할 때까지 기다립니다. 그런 다음 적절한 때가되면 콜백이 이러한 비동기 요청을 실행합니다.

다음은 비동기 코드의 예입니다.

이 예에서는 2 초 후에 만 ​​실행되는 setTimeout 에 “2”가 있으므로 실제로 “1 3 2″를 기록합니다. 2 초 동안 완료 될 때까지 애플리케이션이 중단되지 않습니다. 대신 나머지 코드를 계속 실행하고 시간 초과가 완료되면 afterTwoSeconds로 돌아갑니다.

“이것이 왜 유용합니까?”라고 물어볼 수 있습니다. 또는 “비동기 코드를 동기화하려면 어떻게해야합니까?”. 답을 보여 드릴 수 있기를 바랍니다.

‘문제’

목표는 GitHub 사용자를 검색하고 해당 사용자의 모든 저장소를 가져 오는 것입니다. 문제는 사용자의 정확한 이름을 모른다는 것입니다. 따라서 유사한 이름을 가진 모든 사용자와 해당 저장소를 나열해야합니다.

이렇게 화려할 필요가 없습니다

이 예에서 요청 코드는 XHR (XMLHttpRequest)을 사용합니다. jQuery $. ajax 또는 fetch 라는 최신 기본 접근 방식으로 바꿀 수 있습니다. 둘 다 당신에게 약속을 제공 할 것입니다.

접근 방식에 따라 약간 변경되지만 우선 :

이 예에서 중요한 부분은 코드의 최종 결과가 아님을 기억하십시오. 대신 목표는 접근 방식의 차이점과이를 개발에 활용할 수있는 방법을 이해하는 것이어야합니다.

콜백

자바 스크립트를 사용할 때 변수에 함수 참조를 저장할 수 있습니다. 그런 다음 나중에 실행할 다른 함수의 인수로 사용할 수 있습니다. 이것이 우리의“콜백”입니다.

예 :

콜백 을 사용하여 문제를 해결하면 앞서 정의한 request 함수에 다음과 같은 작업을 수행 할 수 있습니다.

요청에 대한 우리의 함수는 이제 콜백 을 받아 들여 요청 이 만들어 질 때 오류와 성공시 호출 될 것입니다.

분석 :

참고 : 매개 변수로 오류를 먼저 보내는 것은 특히 Node.js를 사용할 때 일반적인 관행입니다.

더 “완전하고”읽기 쉬운 접근 방식은 오류 처리를하는 것입니다. 콜백을 요청 실행과 별도로 유지합니다.

예 :

이로 인해 경주 및 오류 처리 문제와 같은 문제가 발생합니다. 레이싱은 어떤 사용자를 먼저 얻을지 제어하지 않을 때 발생합니다. 둘 이상의 정보가있는 경우 모두에 대한 정보를 요청합니다. 우리는 주문을 고려하지 않습니다. 예를 들어, 사용자 10이 먼저 올 수 있고 사용자 2가 마지막에 올 수 있습니다. 기사 뒷부분에 가능한 해결책이 있습니다.

콜백의 주요 문제는 유지 관리 및 가독성이 고통 스러울 수 있다는 것입니다. 그것은 일종의 이미 있고 코드는 거의 아무것도하지 않습니다. 이를 콜백 지옥 이라고하며 다음 접근 방식으로 피할 수 있습니다.

약속

코드를 더 읽기 쉽게 만들 수 있다고 약속합니다. 새로운 개발자가 코드베이스를 방문하여 코드 실행 순서를 확인할 수 있습니다.

프로 미스를 만들려면 다음을 사용할 수 있습니다.

분해하자 :

유의 사항 :

참고 : 선언시 함수없이 프라 미스를 만들 수 있습니다. 내가 보여주는 방식은 일반적인 방식 일뿐입니다.

“이론, 이론, 이론… 혼란 스럽습니다”라고 말할 수 있습니다.

문제를 해결하겠다는 약속과 함께 요청 예를 사용하겠습니다.

이 시나리오에서 request 를 실행하면 다음과 같은 결과가 반환됩니다.

레이싱 및 일부 오류 처리 문제를 해결하는 방법입니다. 코드는 여전히 약간 복잡합니다. 그러나 이러한 접근 방식이 가독성 문제를 일으킬 수 있음을 보여주는 방법입니다.

빠른 해결 방법은 다음과 같이 콜백을 분리하는 것입니다.

userRequest .then 과 함께 대기중인 순서를 살펴보면이 코드 블록에 대해 우리가 기대하는 바를 알 수 있습니다. 모든 것은 책임에 따라 다소 분리됩니다.

이것은 약속이 무엇인지에 대한“표면을 긁어내는 것”입니다. 작동 방식에 대한 훌륭한 통찰력을 얻기 위해이 기사를 충분히 추천 할 수 없습니다.

발전기

또 다른 접근 방식은 발전기를 사용하는 것입니다. 이것은 조금 더 발전된 것이므로 시작하는 경우 다음 주제로 이동하십시오.

제너레이터의 한 가지 용도는 동기화처럼 보이는 비동기 코드를 가질 수 있다는 것입니다.

함수에서 * 로 표시되며 다음과 같이 표시됩니다.

return 을 반환하는 대신 생성기는 yield 문을 사용합니다. 해당 함수 반복에 대해 .next 가 만들어 질 때까지 함수 실행을 중지합니다. 해결 될 때만 실행되는 .then promise와 유사합니다.

요청 기능은 다음과 같습니다.

url 을 인수로 사용하려고합니다. 그러나 게이트 밖에서 요청을 실행하는 대신 응답을 처리 할 콜백이있을 때만 요청합니다.

생성기 는 다음과 같습니다.

결과 :

따라서 실행은 다음과 같습니다.

이전에했던 것처럼 콜백 함수를 분리 할 수 ​​있습니다. 이제 거래가 완료되었습니다. 중요한 점은 이제 개별 사용자 저장소 목록을 개별적으로 처리 할 수 ​​있다는 것입니다.

나는 발전기에 대해 혼합 벌채를했습니다. 한편으로는 생성기를 살펴봄으로써 코드에서 예상되는 내용을 파악할 수 있습니다.

하지만 그 실행은 결국 콜백 지옥과 비슷한 문제를 안고 있습니다.

async / await와 마찬가지로 컴파일러가 권장됩니다. 이는 이전 브라우저 버전에서 지원되지 않기 때문입니다.

또한 제 경험상 그렇게 흔하지 않습니다. 따라서 다양한 개발자가 관리하는 코드베이스에서 혼란 스러울 수 있습니다.

제너레이터의 작동 방식에 대한 멋진 통찰력은이 문서에서 찾을 수 있습니다. 또 다른 훌륭한 자료가 있습니다.

비동기 / 대기

이 방법은 생성기와 약속이 혼합 된 것처럼 보입니다. 코드에 async 기능이 무엇인지 알려 주기만하면됩니다. 그리고 코드의 어떤 부분이 약속 이 완료되기까지 대기 해야할까요?

이 시나리오에서 :

이를 요청 에 적용하면 앞에서 본 것처럼 약속 으로 남겨 둡니다.

다음과 같이 필요한 await를 사용하여 async 함수를 만듭니다.

이제 요청을 처리 할 비동기 list 함수가 있습니다. forEach 에 또 다른 비동기가 필요하므로 각 사용자가 조작 할 repos 목록이 있습니다.

이름 :

코드를 읽고 변경하기 쉽기 때문에이 방법과 약속 접근 방식이 가장 좋습니다. 여기에서 async / await에 대해 자세히 읽을 수 있습니다.

async / await 사용의 단점은 이전 브라우저의 프런트 엔드 또는 백 엔드에서 지원되지 않는다는 것입니다. Node 8을 사용해야합니다.

이 문제를 해결하기 위해 babel과 같은 컴파일러를 사용할 수 있습니다.

‘솔루션’

이 스 니펫에서 async / await를 사용하여 초기 목표를 달성 한 최종 코드를 볼 수 있습니다.

좋은 방법은이 기사에 언급 된 다양한 형태로 직접 시도해 보는 것입니다.

결론

시나리오에 따라 다음을 사용할 수 있습니다.

목적에 맞는 것은 귀하에게 달려 있습니다. 그리고 다른 사람과 미래의 자신이 이해할 수 있도록 코드를 유지 관리 할 수 ​​있습니다.

참고 : $. ajax fetch 와 같은 요청에 대한 대안을 사용할 때 모든 접근 방식이 약간 덜 장황 해집니다.

각 접근 방식을 더 쉽게 읽을 수 있도록하기 위해 찾은 다양한 방법과 방법을 알려주세요.

이것은 30 개 중 11 조입니다. 유휴 생각에서 튜토리얼에 이르기까지 적어도 일주일에 한 번 기사를 게시하는 프로젝트의 일부입니다. 댓글을 남기고 Diogo Spínola에서 저를 팔로우 한 다음 멋진 프로젝트로 돌아 가세요!