>  기사  >  웹 프론트엔드  >  es5의 Yield 및 es6의 aysnc/await 소개(예제 포함)

es5의 Yield 및 es6의 aysnc/await 소개(예제 포함)

不言
不言앞으로
2019-03-20 10:21:143441검색

이 기사는 es5의 Yield 및 es6의 aysnc/await에 대한 소개를 제공합니다(예제 포함). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

최근 여가 시간에 js 관련 책을 읽고 있으며, Geek Time에서 프론트엔드 관련 칼럼도 구매했습니다. jser가 아닌 사람으로서는 항상 느끼는 바가 있습니다. js 커뮤니티는 정말 급진적이며 이 규칙 제정자들은 구속이 무엇인지 결코 알지 못하는 것 같습니다. 때로는 본질적인 것을 다룰 수 있지만 그들은 인위적으로 몇 가지 개념과 구문 설탕을 만들어내는 것을 선호하며, 인위적으로 산을 쌓지 못한 것 같습니다. 그건 그냥 "신인"입니다

저의 악랄함을 용서해 주세요. "JS Language Essence"를 읽을 때 이 느낌이 매우 강했습니다. 저자는 업계의 대가이고 json도 공식화했지만 여전히 각 장은 그렇습니다. “하찮은 것 같고 철학이 숨어 있다”는 셰익스피어의 명언을 맨 처음에 인용했다. 책에 나오는 많은 내용은 언제나 한 가지 의미를 갖고 있다. 하지만 그렇지는 않습니다. 6점만 말하면 나머지는 스스로 이해할 수 있습니다. 이해로는 이해되지 않는 일반적인 것들이 많지만 몇 마디로 그 본질을 설명하면 갑자기 이해될 수 있습니다. 예전에는 이 사람이 숭배할 산이 너무 크다고 생각했을 겁니다. 비록 지난 몇 년 동안 제 실력이 아직 그렇게 좋지는 않지만, 여전히 내면에 대해 생각하는 것을 좋아하고 열심히 노력하고 있습니다. 마음속의 권위 숭배를 조금씩 없애고 이런 것들을 보면 '...' 이런 문장들이 쉽게 마음에 각인되는 게 한두 사람이 아니라는 생각이 듭니다. js 서클 전체가 이럴 가능성이 높습니다

제목으로 돌아가서 책을 읽고 칼럼을 읽고 정보를 찾는 것 외에도 제너레이터와 async/await를 오랫동안 완전히 이해하지 못했기 때문에 저는 실행중인 전체 프로세스를 정리해 보았습니다

Generator

처음에는 Yield 이후에는 아무것도 따르지 않으려고 했으니 직접 복사해도 됩니다. 콘솔로 출력

function *f0(param) {
    console.log('n: ' + param);
    yield;
    console.log('i');
    let l = yield;
    console.log('l: ' + l);
}
let v0 = f0('p');
console.log(v0.next(1)); // 输出  n: p  和  {value: undefined, done: false}
console.log('----');
console.log(v0.next(2)); // 输出  i  和  {value: undefined, done: false}
console.log('----');
console.log(v0.next(3)); // 输出  l: 3  和  {value: undefined, done: true}
console.log('----');
console.log(v0.next(4)); // 输出 {value: undefined, done: true}
console.log('----');
console.log(v0.next(5)); // 输出 {value: undefined, done: true}

위 내용을 바탕으로 메소드에 반환 값을 줍니다

function *f1() {
    console.log('n');
    yield;
    console.log('i');
    let l = yield;
    console.log('l: ' + l);
    return '?';
}
let v1 = f1();
console.log(v1.next(1));     // 输出  n  和  {value: undefined, done: false}
console.log('----');
console.log(v1.next(11));    // 输出  i  和  {value: undefined, done: false}
console.log('----');
console.log(v1.next(111));   // 输出  l: 111  和  {value: '?', done: true}
console.log('----');
console.log(v1.next(1111));  // 输出 {value: undefined, done: true}
console.log('----');
console.log(v1.next(11111)); // 输出 {value: undefined, done: true}

그런 다음 Yield 이후에 내용을 추가해 보세요

function *f2(param) {
    console.log('0: ' + param);
    let f = yield 1;
    console.log('1: ' + f);
    let s = yield f + 2;
    console.log('2: ' + s);
    let t = yield (s + 3);
    console.log('3: ' + t);
    let fo = (yield s) + 4;
    console.log('4: ' + fo);
}
let v2 = f2('p');
console.log(v2.next('N')); // 输出  0: p  和  {value: 1, done: false}
console.log('----');
console.log(v2.next('I')); // 输出  1: I  和  {value: "I2", done: false}
console.log('----');
console.log(v2.next('L')); // 输出  2: L  和  {value: "L3", done: false}
console.log('----');
console.log(v2.next('S')); // 输出  3: S  和  {value: "L", done: false}
console.log('----');
console.log(v2.next('H')); // 输出  4: H4  和  {value: undefined, done: true}
console.log('----');
console.log(v2.next('I')); // 输出  {value: undefined, done: true}
console.log('----');
console.log(v2.next('T')); // 输出  {value: undefined, done: true}

마지막으로 위 내용을 바탕으로 메소드에 대략적인 반환값을

function *f3() {
    console.log('0');
    let y1 = yield 1;
    console.log('1: ' + y1);
    let y2 = yield y1 + 2;
    console.log('2: ' + y2);
    let y3 = yield (y2 + 3);
    console.log('3: ' + y3);
    let y4 = (yield y3) + 4;
    console.log('4: ' + y4);
    return '??';
}
let v3 = f3();
console.log(v3.next('N')); // 输出  0  和  {value: 1, done: false}
console.log('----');
console.log(v3.next('I')); // 输出  1: I  和  {value: "I2", done: false}
console.log('----');
console.log(v3.next('L')); // 输出  2: L  和  {value: "L3", done: false}
console.log('----');
console.log(v3.next('S')); // 输出  3: S  和  {value: "S", done: false}
console.log('----');
console.log(v3.next('H')); // 输出  4: H4  和  {value: "??", done: true}
console.log('----');
console.log(v3.next('I')); // 输出  {value: undefined, done: true}
console.log('----');
console.log(v3.next('T')); // 输出  {value: undefined, done: true}

부여합니다. 이제 우리는 Yield의 연산 로직을 이해했습니다. 위의 f3을 예로 들어 위의 출력과 비교해 보면 실제로는 나누어집니다. 메소드를 여러 섹션으로 나누어 실행

// 下面  五行一起的竖线(|)  用一个大括号表示出来会更直观一点
function *f3() {
    // 调用第 1 次 next('N') 时运行的代码
    console.log('0');
    let y1 = yield 1;
    return 1;                          // | 封装成 {value: 1, done: false} 返回
                                       // |
                                       // | 这两行等同于 let y1 = yield 1;
    // 调用第 2 次 next('I') 时运行的代码 // |
    let y1 = 'I';                      // |
    console.log('1: ' + y1);
    return y1 + 2;                     // | 封装成 {value: "I2", done: false} 返回
                                       // |
                                       // | 这两行等同于 let y2 = yield y1 + 2;
    // 调用第 3 次 next('L') 时运行的代码 // |
    let y2 = 'L';                      // |
    console.log('2: ' + y2);
    return y2 + 3;                     // | 封装成 {value: "L3", done: false} 返回
                                       // |
                                       // | 这两行等同于 let y3 = yield (y2 + 3);
    // 调用第 4 次 next('S') 时运行的代码 // |
    let y3 = 'S';                      // |
    console.log('3: ' + y3);
    return y3;                         // | 封装成 {value: "S", done: false} 返回
                                       // |
                                       // | 这两行等同于 let y4 = (yield y3) + 4;
    // 调用第 5 次 next('H') 时运行的代码 // |
    let y4 = 'H'                       // |
    console.log('4: ' + y4);
    return '??';                       // 封装成 {value: "??", done: true} 返回
}

다시 생각해 보면 처음 실행될 때 next('N')을 사용할 때 전달된 N은 무시됩니다. next()는 처음으로 받을 수 있는 Yield가 없습니다. 책을 읽든, 찾은 기사를 읽든 첫 번째는 next()에 한 번만 전달되는 매개변수가 아닙니다. for는 반복을 위해 사용할 수 있지만 왜 이렇게 포장되어 있는지는 모르겠습니다. next()가 실행될 때마다 해당 섹션이 실행되기 때문에 재미를 위해 새로운 것일 수 있습니다. 는 "드디어 비동기화 가능"이라고도 불립니다

async/await

그리고 es7이 말하기 시작한 이 두 가지 열쇠가 있는데, 저는 주요 제조업체의 인터뷰 질문을 읽고 이에 대한 이해를 깊게 하기 위해 두 개의 키워드를 다음과 같이 변경했습니다.

async function async1() {
    console.log('A');
    console.log(await async2());
    return 'B';
}
async function async2() {
    console.log('C');
    return 'D';
}
console.log('E');
setTimeout(function() {
    console.log('F');
}, 0);
async1().then(function(r) {
    console.log(r);
});
new Promise(function(resolve, reject) {
    console.log('G');
    resolve();
}).then(function() {
    console.log('H');
});
console.log('I');

chrome 73.0.3683.75의 출력은

// 这个 undefined 的意思应该主要是用来分隔宏任务的, 也就是前面的主线和任务队列是在一起的
E  A  C  G  I  D  H  B  undefined  F

firefox 60.5.1의

// 这个 undefined 的意思应该只是用来分隔主线的, 任务队列和宏任务在一起了
E  A  C  G  I  undefined  H  D  B  F

Opera 58.0.3135.107의 출력은

// 这个 undefined 应该跟 chrome 里面是一样的
E  A  C  G  I  H  D  B  undefined  F

분명히 DH B가 더 합리적입니다. . Firefox 및 Opera 구현에는 분명히 문제가 있습니다. 더 낮은 버전의 Chrome도 뒤처져 있을 수 있습니다. 결과

final

와 var let const와 같은 간단한 할당을 사용하면 많은 트릭을 사용할 수 있습니다. 물론 역사적 문제 때문이라고 할 수도 있음)

솔직히 "다른 언어에도 있는데 당연히 우리 같은 아방가르드 언어에도 있어야지!"

...

이러한 언어가 지금처럼 인기를 얻으려면 이 세상이 정말 놀랍다고밖에 말할 수 없습니다.

이 기사는 여기서 끝났습니다. 더 흥미로운 내용을 보려면

JavaScript 튜토리얼을 참조하세요. PHP 중국어 홈페이지의 영상

칼럼!

위 내용은 es5의 Yield 및 es6의 aysnc/await 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제