기술나눔

ES6 비동기 기능에 대한 자세한 설명 (10)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

비동기 기능이란 무엇입니까? 한마디로 이것은 Generator 함수의 구문 설탕입니다.

const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

async 함수는 Generator 함수의 별표(*)를 async로 바꾸고, Yield를 Wait로 바꾸는 것뿐입니다.

Generator 함수에 대한 async 함수의 개선 사항은 다음 네 가지 사항에 반영됩니다.

(1) 내장형 액추에이터.
Generator 함수의 실행은 실행기에 의존해야 하므로 co 모듈이 있고 async 함수에는 자체 실행기가 함께 제공됩니다. 즉, 비동기 함수의 실행은 한 줄만 있으면 일반 함수와 완전히 동일합니다.

co 모듈: co 모듈은 유명한 프로그래머 TJ Holowaychuk이 2013년 6월에 출시한 작은 도구로, Generator 기능의 자동 실행에 사용됩니다.
co 모듈을 사용하면 Generator 함수의 실행 프로그램을 작성하지 않아도 됩니다.

// Generator 函数
var gen = function* () {
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

//co模块使用
var co = require('co');
co(gen); //co 函数返回一个 Promise 对象
co(gen).then(function (){
  console.log('Generator 函数执行完成');
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(2) 더 나은 의미론.
Async 및 Wait는 별표 및 Yield보다 의미가 더 명확합니다. async는 함수에 비동기 작업이 있음을 의미하고, wait는 다음 표현식이 결과를 기다려야 함을 의미합니다.
(3) 적용 범위가 넓어졌습니다.
co 모듈 규칙에 따르면, Yield 명령 뒤에는 Thunk 함수 또는 Promise 객체만 올 수 있고, 비동기 함수의 Wait 명령 뒤에는 Promise 객체와 기본 유형 값(숫자 값, 문자열 및 부울)이 올 수 있습니다. 값이지만 자동으로 즉시 해결되는 Promise 객체로 변환됩니다.
(4) 반환 값은 Promise입니다.
비동기 함수의 반환 값은 Promise 객체이므로 Generator 함수의 반환 값이 Iterator 객체인 것보다 훨씬 편리합니다. then 메소드를 사용하여 다음 작업을 지정할 수 있습니다.

또한 async 함수는 Promise 객체로 패키징된 여러 비동기 작업으로 간주될 수 있으며, wait 명령은 내부 then 명령의 구문적 설탕입니다.

1. 기본 비동기 기능

// 定义一个异步函数
async function fetchData() {
    return 'Data fetched';
}

// 调用异步函数
fetchData().then(data => {
    console.log(data); // 输出: Data fetched
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2. Promise를 기다리려면 wait를 사용하세요.

// 模拟一个异步请求函数
function getUserData() {
    return new Promise(resolve => {
        setTimeout(() => resolve({ name: 'Alice' }), 1000);
    });
}

// 异步函数使用 await 等待 Promise
async function printUserData() {
    try {
        const userData = await getUserData();
        console.log(userData); // 输出: { name: 'Alice' }
    } catch (error) {
        console.error(error);
    }
}

printUserData();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3. 오류 처리

// 异步函数中的错误处理
async function riskyFunction() {
    try {
        const result = await Promise.reject('An error occurred');
    } catch (error) {
        console.error(error); // 输出: An error occurred
    }
}

riskyFunction();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4. 연결된 비동기 기능

async function asyncOperation() {
    return 'Operation completed';
}

async function chainAsyncFunctions() {
    try {
        const result1 = await asyncOperation();
        const result2 = await asyncOperation();
        console.log(result1, result2); // 输出: Operation completed Operation completed
    } catch (error) {
        console.error(error);
    }
}

chainAsyncFunctions();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5. 이벤트 처리 기능으로서의 비동기 기능

// 假设有一个按钮元素
const button = document.querySelector('#myButton');

// 为按钮添加点击事件处理函数
button.addEventListener('click', async event => {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

6. 비동기 함수와 Promise.all

// 异步函数返回多个 Promise
async function fetchUsers() {
    return ["User1", "User2", "User3"];
}

async function fetchPosts() {
    return ["Post1", "Post2", "Post3"];
}

// 使用 Promise.all 并行处理多个异步操作
async function fetchAllData() {
    try {
        const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
        console.log(users, posts); // 输出: [ 'User1', 'User2', 'User3' ] [ 'Post1', 'Post2', 'Post3' ]
    } catch (error) {
        console.error(error);
    }
}

fetchAllData();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20