programing

JavaScript에서 yield 키워드는 무엇입니까?

goodjava 2022. 12. 30. 17:11

JavaScript에서 yield 키워드는 무엇입니까?

JavaScript에서 "수익률" 키워드에 대해 들어본 적이 있지만, 그에 대한 문서가 매우 빈약하다는 것을 발견했습니다.그 용도와 용도를 설명해 주실 수 있습니까(또는 그 사이트를 추천해주세요.

늦다, 있을 것이다yield지만만더더더더문문문나다다

"Javascript's Future"의 예를 채택합니다. James Long의 공식 Harmony 표준에 대한 발전기:

function * foo(x) {
    while (true) {
        x = x * 2;
        yield x;
    }
}

"foo를 호출하면 다음 메서드가 있는 제너레이터 개체가 반환됩니다."

var g = foo(2);
g.next(); // -> 4
g.next(); // -> 8
g.next(); // -> 16

★★★★★★★★★★★★★★★★★.yield ★★★★★★★★★★★★★★★.return 가가돌돌돌돌돌돌 return x에 의해 값이 반환됩니다.xyield x함수를 반환하면 다음 값으로 반복하는 메서드가 제공됩니다.반복 중에 중단해야 할 가능성이 있는 메모리 사용량이 많은 절차가 있는 경우에 유용합니다.

매우 심플합니다.이렇게 동작합니다.

  • yield키워드는 비동기적으로 언제든지 기능을 일시정지 및 재개하는 데 도움이 됩니다.
  • 또한 제너레이터 함수에서 값을 반환하는 데 도움이 됩니다.

다음과 같은 간단한 발전기 함수를 예로 들어 보겠습니다.

function* process() {
    console.log('Start process 1');
    console.log('Pause process2 until call next()');

    yield;

    console.log('Resumed process2');
    console.log('Pause process3 until call next()');

    let parms = yield {age: 12};
    console.log("Passed by final process next(90): " + parms);

    console.log('Resumed process3');
    console.log('End of the process function');
}

_process = process();

_process.next()를 호출할 때까지 코드번째 2행은 실행되지 않습니다.그 후 첫 번째 출력은 함수를 일시 정지합니다.다음 포즈 포인트(yield 키워드)까지 기능재개하려면 _process.next()를 호출해야 합니다.

여러 개의 수율이 단일 함수 내의 Javascript 디버거의 중단점이라고 생각할 수 있습니다.다음 브레이크 포인트를 탐색하도록 지시할 때까지 코드 블록은 실행되지 않습니다.(주의: 어플리케이션 전체를 차단하지 않음)

그러나 이 일시 중지 및 재개 동작을 수행하는 동안 일부 결과도 반환할 수 있습니다.{value: any, done: boolean}이전 함수에 따르면 우리는 어떤 가치도 방출하지 않습니다.됩니다.{ value: undefined, done: false }을 정의하지 않았습니다.

weat 키워드에 대해 자세히 알아보겠습니다.선택적으로 식을 추가하고 기본 옵션 값을 할당하도록 설정할 수 있습니다(공식 문서 구문)

[rv] = yield [expression];

expression: 제너레이터 함수에서 반환할 값

yield any;
yield {age: 12};

rv: 제너레이터의 next() 메서드에 전달된 선택적 값을 반환합니다.

단순히 이 메커니즘으로 파라미터를 process() 함수에 전달하여 다른 항복 부품을 실행할 수 있습니다.

let val = yield 99; 

_process.next(10);
now the val will be 10 

지금 바로 시험해 보세요

사용법

  • 게으른 평가
  • 무한 시퀀스
  • 비동기 제어 흐름

참고 자료:

MDN의 문서는 꽤 훌륭합니다, IMO.

yield 키워드를 포함하는 함수는 제너레이터입니다.호출할 때 형식 파라미터는 실제 인수에 구속되지만 본문은 실제로 평가되지 않습니다.대신 제너레이터 반복기가 반환됩니다.generator-iterator의 next() 메서드에 대한 각 호출은 반복 알고리즘을 통해 다른 경로를 수행합니다.각 스텝의 값은 yield 키워드로 지정된 값입니다.산출량은 알고리즘의 각 반복 사이의 경계를 나타내는 수익의 생성기-반복기 버전이라고 생각하십시오.next()를 호출할 때마다 생성기 코드는 항복에 이어 문장에서 재개됩니다.

Nick Sotiros의 을 어떻게 가장 합니다.yield.

때 in, 제, 제, 용의 가장 큰 , 용, 용, 용을 사용하는 것입니다.yield코드에서 볼 수 있는 네스트된 콜백 문제를 모두 없앤다는 것입니다.처음에는 어떻게 하는지 알기 어렵기 때문에 이 답을 쓰기로 결심했습니다(나 자신, 그리고 바라건대 다른 사람들을 위해서).

코루틴의 개념을 도입하면 필요한 것을 얻을 때까지 자발적으로 정지/일시정지할 수 있습니다.를 javascript로 .function* 만.function*는 「」를 사용할 수 .yield.

다음은 일반적인 Javascript입니다.

loadFromDB('query', function (err, result) {
  // Do something with the result or handle the error
})

코드에는 가 있다)가 포함되어 있기 .loadFromDBcall은 이 흉한 call) 안에 ." " " " " " " " " "

  • 코드 전체가 한 단계씩 들여쓰기되어 있습니다.
  • .}) 곳을 .
  • 추가 정보function (err, result)
  • '가치를 '라고 하는 .result

★★★★★★★★★★★★★★★★★★★★★에서는,yield이 모든 것은 훌륭한 공동 작업 프레임워크의 도움으로 한 에 걸쳐 수행할 수 있습니다.

function* main() {
  var result = yield loadFromDB('query')
}

따라서 이제 주요 기능이 필요한 경우 변수와 항목이 로드될 때까지 기다려야 합니다.그러나 이 기능을 실행하려면 일반(비 Coroutine 함수)을 호출해야 합니다.간단한 코루틴 프레임워크로 이 문제를 해결할 수 있으므로 다음 작업만 수행하면 됩니다.

start(main())

그리고 시작은 (Nick Sotiro의 답변에서) 정의된다.

function start(routine, data) {
    result = routine.next(data);
    if(!result.done) {
        result.value(function(err, data) {
            if(err) routine.throw(err); // continue next iteration of routine with an exception
            else start(routine, data);  // continue next iteration of routine normally
        });
    }
}

이제 훨씬 읽기 쉽고 삭제하기 쉬우며 들여쓰기나 함수 등을 만질 필요가 없는 아름다운 코드를 만들 수 있습니다.

에서 관찰할 수 있는 것은 이 예에서 볼 수 있다.yield는 실제로는 콜백을 가진 함수 앞에 붙일 수 있는 키워드일 뿐입니다.

function* main() {
  console.log(yield function(cb) { cb(null, "Hello World") })
}

" World출력할 거야Hello World'는 어떤 실제로 사용할 수 .yield를 사용하지 않고) 하여 (cb를 하지 않고) 반환하는 function (cb) {}다음과 같이 합니다.

function yieldAsyncFunc(arg1, arg2) {
  return function (cb) {
    realAsyncFunc(arg1, arg2, cb)
  }
}

이 지식을 통해 삭제하기 쉬운 더 깨끗하고 읽기 쉬운 코드를 작성할 수 있기를 바랍니다!

Yield의 키워드를 .

JavaScript의 generator란 무엇입니까?

생성기는 단일 값 대신 일련의 값을 생성하는 함수입니다. 즉, 일련의 값을 생성합니다.

의미 생성기는 도움말 반복기와 비동기적으로 작업할 수 있도록 도와줍니다. 오, 이제 해킹 반복기가 뭐죠? 정말요?

반복기는 한 번에 하나씩 항목에 액세스할 수 있는 수단입니다.

반복기에서 한 번에 하나씩 항목에 액세스할 수 있습니다.기능을 통해 할 수 , 입니다.yield키워드, yield 키워드를 지정하면 기능 실행을 일시 중지 및 재개할 수 있습니다.

다음으로 간단한 예를 제시하겠습니다.

function *getMeDrink() {

    let question1 = yield 'soda or beer'; // execution will pause here because of yield
       
    if (question1 == 'soda') {
        return 'here you get your soda';
    }

    if (question1 == 'beer') {

        let question2 = yield 'What\'s your age'; // execution will pause here because of yield

        if (question2 > 18) {
            return "ok you are eligible for it";
        } else {
            return "Shhhh!!!!";
        }
    }
}

let _getMeDrink = getMeDrink(); // initialize it

_getMeDrink.next().value; // "soda or beer"

_getMeDrink.next('beer').value; // "What's your age"

_getMeDrink.next('20').value; // "ok you are eligible for it"

_getMeDrink.next().value; // undefined

무슨 일이 일어나고 있는지 간단히 설명하겠습니다.

알 수 .yield하면, 로 액세스 할 수 .yield.next()

은 모든 된다.yield후, 「1」이 , 로 되돌립니다.yield는 '어느 쪽이든'이라고 할 수 있습니다.yield는 이입니다._getMeDrink.next()이 예는 기능의 각 중단점에 액세스하는 데 도움이 되는 반복기의 예입니다.

예: " " " "async/await

「」의 실장이 .async/await 될 것이다generator functions & promises 때 합니다.async/await어떤 제안이라도 환영한다는 점을 지적해 주십시오.

답변을 , 「 」를 참조해 주세요.yield와 비슷하게 동작하고 있다.return발전기 안에서요

일반적인 예에 대해서는, 다음과 같이 동작합니다.

function *squareGen(x) {
    var i;
    for (i = 0; i < x; i++) {
        yield i*i;
    }
}

var gen = squareGen(3);

console.log(gen.next().value); // prints 0
console.log(gen.next().value); // prints 1
console.log(gen.next().value); // prints 4

단, 이 키워드의 두 번째 목적도 있습니다.값을 제너레이터로 전송하는 데 사용할 수 있습니다.

간단히 설명하자면 다음과 같습니다.

function *sendStuff() {
    y = yield (0);
    yield y*y;
}

var gen = sendStuff();

console.log(gen.next().value); // prints 0
console.log(gen.next(2).value); // prints 4

으로서 기능합니다.2 is is is is is 。y 수율(반환)에서)0를 참조해 주세요.

이렇게 하면 정말 펑키한 것들을 할 수 있습니다.(coroutine 검색)

반복 발전기 발전기에 사용됩니다.기본적으로 절차 코드를 사용하여 (잠재적으로 무한한) 시퀀스를 만들 수 있습니다.Mozilla의 설명서를 참조하십시오.

yield는 Coroutine 프레임워크를 사용하여 콜백헬을 제거하는 데도 사용할 수 있습니다.

function start(routine, data) {
    result = routine.next(data);
    if(!result.done) {
        result.value(function(err, data) {
            if(err) routine.throw(err); // continue next iteration of routine with an exception
            else start(routine, data);  // continue next iteration of routine normally
        });
    }
}

// with nodejs as 'node --harmony'
fs = require('fs');
function read(path) {
    return function(callback) { fs.readFile(path, {encoding:'utf8'}, callback); };
}

function* routine() {
    text = yield read('/path/to/some/file.txt');
    console.log(text);
}

// with mdn javascript 1.7
http.get = function(url) {
    return function(callback) { 
        // make xhr request object, 
        // use callback(null, resonseText) on status 200,
        // or callback(responseText) on status 500
    };
};

function* routine() {
    text = yield http.get('/path/to/some/file.txt');
    console.log(text);
}

// invoked as.., on both mdn and nodejs

start(routine());

yield 키워드를 사용한 피보나치 시퀀스 생성기.

function* fibbonaci(){
    var a = -1, b = 1, c;
    while(1){
        c = a + b;
        a = b;
        b = c;
        yield c;
    }   
}

var fibonacciGenerator = fibbonaci();
fibonacciGenerator.next().value; // 0 
fibonacciGenerator.next().value; // 1
fibonacciGenerator.next().value; // 1
fibonacciGenerator.next().value; // 2 

비동기 javascript 호출 간의 의존 관계.

수율을 어떻게 사용할 수 있는지에 대한 또 다른 좋은 예입니다.

function request(url) {
  axios.get(url).then((reponse) => {
    it.next(response);
  })
}

function* main() {
  const result1 = yield request('http://some.api.com' );
  const result2 = yield request('http://some.otherapi?id=' + result1.id );
  console.log('Your response is: ' + result2.value);
}

var it = main();
it.next()

수율에 대해 배우기 전에 생성기에 대해 알아야 합니다.는 '생성하다'를 됩니다.function*구문을 사용합니다.제너레이터 함수는 코드를 실행하지 않고 제너레이터라는 반복기 유형을 반환합니다." " 를 next방법, 제너레이터의 수율.「」를 사용합니다.yield는 2개의 값(하나는 값, 다른 하나는 실행)을 포함하는 개체를 반환합니다.값은 배열, 객체 등이 될 수 있습니다.

간단한 예:

const strArr = ["red", "green", "blue", "black"];

const strGen = function*() {
    for(let str of strArr) {
        yield str;
    }
};

let gen = strGen();

for (let i = 0; i < 5; i++) {
    console.log(gen.next())
}

//prints: {value: "red", done: false} -> 5 times with different colors, if you try it again as below:

console.log(gen.next());

//prints: {value: undefined, done: true}

저도 yield 키워드를 이해하려고 노력 중입니다.현재 이해한 바에 따르면 제너레이터에서 yield 키워드는 CPU 컨텍스트스위치와 같이 동작합니다.yield 문을 실행하면 모든 상태(예: 로컬 변수)가 저장됩니다.

이 외에도 {value: 0, done: false}와 같은 직접 결과 개체가 호출자에게 반환됩니다.호출자는 이 결과 개체를 사용하여 next()를 호출하여 제너레이터를 다시 웨이크업할지 여부를 결정할 수 있습니다(next() 호출은 실행을 반복하는 것입니다).

또 하나의 중요한 점은 로컬 변수에 값을 설정할 수 있다는 것입니다.이 값은 제너레이터를 '웨이크업'할 때 'next()' 호출자가 전달할 수 있습니다.예를 들어, it.next("valueToPass")와 같이 "Value = yield slowQuery(1);"와 같이 호출자는 다음 실행 시 실행 결과를 주입할 수 있습니다(로컬 변수에 포함).따라서 이 실행에는 다음 두 가지 상태가 있습니다.

  1. 마지막 실행에서 저장한 컨텍스트입니다.

  2. 이 실행 트리거에 의해 주입된 값입니다.

따라서 이 기능을 통해 제너레이터는 여러 비동기 작업을 정렬할 수 있습니다.첫 번째 비동기 쿼리의 결과는 로컬 변수를 설정하여 두 번째 쿼리로 전달됩니다(위의 예에서는 값).두 번째 비동기 쿼리는 첫 번째 비동기 쿼리의 응답에 의해서만 트리거될 수 있습니다.로컬 변수는 첫 번째 쿼리의 응답에서 주입된 값이기 때문에 두 번째 비동기 쿼리는 로컬 변수 값을 확인하여 다음 단계를 결정할 수 있습니다.

비동기 쿼리의 어려움은 다음과 같습니다.

  1. 콜백 지옥

  2. 콜백의 파라미터로 전달하지 않는 한 컨텍스트가 손실됩니다.

수율 및 발전기가 두 가지 모두에 도움이 됩니다.

yield 와 generator 를 사용하지 않는 경우 여러 비동기 쿼리를 정렬하려면 파라미터가 컨텍스트로 포함된 네스트된 콜백이 필요하며 읽기 및 유지보수가 용이하지 않습니다.

다음으로 nodej에서 실행되는 연쇄 비동기 쿼리의 예를 나타냅니다.

const axios = require('axios');

function slowQuery(url) {        
    axios.get(url)
    .then(function (response) {
            it.next(1);
    })
    .catch(function (error) {
            it.next(0);
    })
}

function* myGen(i=0) {
    let queryResult = 0;

    console.log("query1", queryResult);
    queryResult = yield slowQuery('https://google.com');


    if(queryResult == 1) {
        console.log("query2", queryResult);
        //change it to the correct url and run again.
        queryResult = yield slowQuery('https://1111111111google.com');
    }

    if(queryResult == 1) {
        console.log("query3", queryResult);
        queryResult =  yield slowQuery('https://google.com');
    } else {
        console.log("query4", queryResult);
        queryResult = yield slowQuery('https://google.com');
    }
}

console.log("+++++++++++start+++++++++++");
let it = myGen();
let result = it.next();
console.log("+++++++++++end+++++++++++");

실행 결과는 다음과 같습니다.

++++++++++시작+++++++++++++.

query1 0

+++++++++++++ 종료+++++++++++++

쿼리2 1

query4 0

다음 상태 패턴은 위의 예와 같은 작업을 수행할 수 있습니다.

const axios = require('axios');

function slowQuery(url) {
    axios.get(url)
        .then(function (response) {
            sm.next(1);
        })
        .catch(function (error) {
            sm.next(0);
        })
}

class StateMachine {
        constructor () {
            this.handler = handlerA;
            this.next = (result = 1) => this.handler(this, result);
        }
}

const handlerA = (sm, result) => {
                                    const queryResult = result; //similar with generator injection
                                    console.log("query1", queryResult);
                                    slowQuery('https://google.com');
                                    sm.handler = handlerB; //similar with yield;
                                };

const handlerB = (sm, result) => {
                                    const queryResult = result; //similar with generator injection
                                    if(queryResult == 1) {
                                        console.log("query2", queryResult);
                                        slowQuery('https://1111111111google.com');
                                    }
                                    sm.handler = handlerC; //similar with yield;
                                };

const handlerC = (sm, result) => {
                                    const queryResult = result; //similar with generator injection;
                                    if (result == 1 ) {
                                        console.log("query3", queryResult);
                                        slowQuery('https://google.com');
                                    } else {
                                        console.log("query4", queryResult);
                                        slowQuery('https://google.com');
                                    }
                                    sm.handler = handlerEnd; //similar with yield;
                                };

const handlerEnd = (sm, result) => {};

console.log("+++++++++++start+++++++++++");
const sm = new StateMachine();
sm.next();
console.log("+++++++++++end+++++++++++");

실행 결과는 다음과 같습니다.

++++++++++시작+++++++++++++.

query1 0

+++++++++++++ 종료+++++++++++++

쿼리2 1

query4 0

제너레이터를 루프할 때 매우 유용한 'x of generator' 구문을 잊지 마십시오.next() 함수를 사용할 필요가 없습니다.

function* square(x){
    for(i=0;i<100;i++){
        x = x * 2;
        yield x;        
    }   
}

var gen = square(2);
for(x of gen){
   console.log(x);
}

언급URL : https://stackoverflow.com/questions/2282140/whats-the-yield-keyword-in-javascript