> 웹 프론트엔드 > JS 튜토리얼 > JavaScript를 사용하는 비동기보다 더 나은 솔루션이 있습니까?

JavaScript를 사용하는 비동기보다 더 나은 솔루션이 있습니까?

亚连
풀어 주다: 2018-06-13 11:40:30
원래의
1277명이 탐색했습니다.

이 기사에서는 주로 비동기 JavaScript를 경험하기 위한 더 나은 솔루션을 설명합니다. 이 측면이 필요한 친구는 참고할 수 있습니다.

1. 비동기 솔루션의 진화 역사
JavaScript의 비동기 작업은 항상 골치 아픈 문제였기 때문에 사람들은 이에 대한 다양한 솔루션을 계속 제안하고 있습니다. 최초의 콜백 함수(ajax의 오랜 친구), Promise(새 친구 아님), 그리고 ES6 Generator(강력한 친구)까지 추적할 수 있습니다.
몇 년 전에는 유명한 Async.js를 사용했을 수도 있지만 콜백 함수를 없애지 않았으며 오류 처리도 "콜백 함수의 첫 번째 매개 변수를 사용하여 오류를 전달하는 데 사용됩니다"라는 규칙을 따랐습니다. 잘 알려진 콜백 지옥은 Generator가 이 비동기 스타일을 변경할 때까지 여전히 두드러진 문제였습니다.
그러나 ES7의 비동기 대기(Bunker의 새로운 친구)가 등장하면서 비동기 메커니즘을 가지면서 동기 스타일 코드를 쉽게 작성할 수 있게 되었습니다. 이는 현재 가장 간단하고 우아하며 최고의 솔루션이라고 할 수 있습니다.

2. 비동기 대기 구문
async 대기 구문은 상대적으로 간단하며 별표 및 수율보다 더 의미론적입니다. 다음은 1초 후에 hello world를 출력하는 간단한 예입니다.

function timeout(ms) {
 return new Promise((resolve) => {
  setTimeout(resolve, ms);
 });
}
async function asyncPrint(value, ms) {
 await timeout(ms);
 console.log(value)
}
asyncPrint('hello world', 1000);
로그인 후 복사

await는 비동기 함수에서만 사용할 수 있습니다. 일반 함수에서 사용하면

await 뒤에 Promise 객체가 따라옵니다(물론). 다른 값도 사용할 수 있지만 즉시 해결되는 Promise로 패키징되므로 의미가 없습니다.)

await는 실행을 계속하기 전에 Promise의 결과가 반환될 때까지 기다립니다.

await는 Promise 객체이지만 .then()을 작성할 필요가 없습니다. 반환 값을 직접 얻을 수 있고 위 코드를 미세 조정하여 반환 값 결과가 hello world도 출력할 수 있음을 발견했습니다.

function timeout(ms) {
 return new Promise((resolve) => {
  setTimeout(_ => {resolve('hello world')}, ms);
 });
}
async function asyncPrint(ms) {
 let result = await timeout(ms);
 console.log(result)
}
asyncPrint(1000);
로그인 후 복사

3. async wait 오류 처리

앞서 언급했듯이 Wait는 Promise 객체를 기다리고 있지만 .then()을 작성할 필요가 없으므로 실제로 .catch()를 작성할 필요가 없습니다. try catch를 사용하여 직접 오류를 잡을 수 있습니다. . 이렇게 하면 중복되고 번거로운 오류 처리 코드를 피할 수 있습니다. 위의 예를 미세 조정해 보겠습니다.

function timeout(ms) {
 return new Promise((resolve, reject) => {
  setTimeout(_ => {reject('error')}, ms);//reject模拟出错,返回error
 });
}
async function asyncPrint(ms) {
 try {
   console.log('start');
   await timeout(ms);//这里返回了错误
   console.log('end');//所以这句代码不会被执行了
 } catch(err) {
   console.log(err); //这里捕捉到错误error
 }
}
asyncPrint(1000);
로그인 후 복사

여러 개의 대기 항목이 있는 경우 함께 배치할 수 있습니다. try catch:

async function main() {
 try {
  const async1 = await firstAsync();
  const async2 = await secondAsync();
  const async3 = await thirdAsync();
 }
 catch (err) {
  console.error(err);
 }
}
로그인 후 복사

4. 비동기 대기에 대한 참고 사항

1) 앞서 언급했듯이, wait 명령 뒤에 있는 Promise 개체는 거부 또는 논리적 오류를 초래할 가능성이 높으므로 try catch 코드 블록에 wait를 넣는 것이 가장 좋습니다.

2) 여러 대기 명령의 비동기 작업의 경우 종속성이 없으면 동시에 트리거되도록 합니다.

const async1 = await firstAsync();
const async2 = await secondAsync();
로그인 후 복사

위 코드에서 async1과 async2가 두 개의 독립적인 비동기 작업인 경우 firstAsync가 완료될 때까지 secondAsync가 실행되지 않기 때문에 이렇게 작성하는 것이 더 시간이 많이 걸립니다. Promise.all을 사용하여 우아하게 처리할 수 있습니다. :

let [async1, async2] = await Promise.all([firstAsync(), secondAsync()]);
로그인 후 복사

3) Wait는 비동기 함수에서만 사용할 수 있습니다. 일반 함수에서 사용하면 오류가 보고됩니다.

async function main() {
 let docs = [{}, {}, {}];
 //报错 await is only valid in async function
 docs.forEach(function (doc) {
  await post(doc);
  console.log('main');
 });
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}
로그인 후 복사

forEach 내부 메서드에 async를 추가하면 됩니다.

async function main() {
 let docs = [{}, {}, {}];
 docs.forEach(async function (doc) {
  await post(doc);
  console.log('main');
 });
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}
로그인 후 복사

하지만 3가지 주요 기능을 찾을 수 있습니다. 이는 post가 순차적이 아닌 동시에 실행된다는 의미입니다. for 으로 변경하면 문제를 해결할 수 있습니다.

async function main() {
 let docs = [{}, {}, {}];
 for (let doc of docs) {
  await post(doc);
  console.log('main');
 }
}
function post(){
 return new Promise((resolve) => {
  setTimeout(resolve, 1000);
 });
}
로그인 후 복사

간단히 말하면 async wait를 사용한 후 기분이 상쾌해집니다. 매우 간결하고 우아한 코드를 사용하여 다양한 멋진 비동기 작업을 구현할 수 있으며 비즈니스 로직이 복잡할 때 콜백 지옥에 빠질 필요가 없습니다. 이것이 궁극적인 해결책이라고 감히 말할 수는 없지만 실제로 현재 가장 우아한 해결책입니다!

위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다.

관련 기사:

How to 통합 zTree 코드를 Angular

노드 패키징 도구 Pkg(자세한 튜토리얼)

js를 사용하여 WeChat에서 앱을 호출하는 방법은 무엇입니까?

위 내용은 JavaScript를 사용하는 비동기보다 더 나은 솔루션이 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿