programing

ES6 제너레이터: 반복기의 스택 트레이스가 불량합니다.던지다 (err)

newsource 2023. 9. 12. 20:04

ES6 제너레이터: 반복기의 스택 트레이스가 불량합니다.던지다 (err)

ES6 방법:iterator.throw(err)종종 예외를 주입하는 것으로 묘사됩니다. 마치 그것이 발생한 것처럼.yield생성기에 있는 문장.문제는 이 예외에 대한 스택 트레이스에 수율 문에 대한 파일/행에 대한 참조 또는 해당 함수가 포함되어 있지 않다는 것입니다.오히려 스택 트레이스는 예외 개체를 구성할 때만 생성되는 것으로 보이며, 이 개체는 내부에 있지 않습니다.generator.

문제는 어떻게 하면 스택 트레이스 또는 다른 방법으로 위반되는 수익률 진술의 위치를 알 수 있을까 하는 것입니다.

function* one_of_many_generators() {
    // ...
    yield ajax(url);    // <-- what I need in the stack trace
    // ...
}

function outer() {
    var iterator = one_of_many_generators();
    iterator.next();    // runs to the first yield

    // inject exception at the yield statement
    iterator.throw(Error("error"));   // <-- top of stack trace shows here
}

이 문제는 특정한 것이 아님에도 불구하고Promises, 그들은 그 문제를 더 쉽게 상상하게 할 수 있습니다.저의 경우 발전기와 약속이 있는 업무 시스템을 사용하고 있습니다.가상 함수는ajax()는 약속을 반환하고, 이를 거부할 경우 이 메커니즘을 사용하여 오류를 양보문에 던지는 것으로 변환합니다.

디버거의 스택 트레이스는 이 인젝션이 발생하는 위치에 대한 함수, 파일 또는 라인 번호를 가져올 방법을 찾을 수 없기 때문에 상당히 쓸모가 없습니다.부르기iterator.throw(err)재던져지는 것처럼 취급되며, 새로운 스택 정보를 얻지 못하므로 내부에 위치만 표시합니다.ajax()많은 장소에서 호출될 수 있는 함수, 그리고 새로운 오류를 던짐으로써.outer()위의 예와 같이 모든 오류에 대해 동일한 throw line이 표시됩니다.둘 다 무엇에 대해 힌트를 주지 않습니다.generator오류 디버깅을 위해 함수를 실행 중입니다.


Chrome v42를 사용하고 있습니다.

반복자와 약속은 잘 섞이지 않습니다. 즉, 기본적으로 약속을 양보하는 것이고 그 후에 실패하는 것입니다.

약속의 결과를 발전기에 전달하면 이 문제를 해결할 수 있습니다. 예를 들어 다음과 같습니다.

function* one_of_many_generators() {
    // ...
    var promiseResult = yield ajax(url);    // <-- what I need in the stack trace

    // Now we're back in the generator with the result of the promise
    if(notHappyWithResult(promiseResult))
        throw new Error('Reason result is bad');
    // ...
}

async function outer() {
    var iterator = one_of_many_generators();
    let prms = iterator.next();    // runs to the first yield

    // Wait for the promise to finish
    let result = await prms;

    // Pass the result back to the generator
    let whatever = iterator.next(result);
}

오직: 이것은 일종의 것입니다.async그리고.await어쨌든 하세요 (이 키워드들은 단지 결과가 전달된 약속의 생성자를 위한 통사적 설탕일 뿐입니다) 그리고 만일 당신이 그것들을 규칙적으로 사용한다면.try-catch효과가 있을 겁니다

iterator.throw주로 반복을 중지하는 방법이며, 예외를 다시 주입하지 않습니다. 스택 상단은 여전히 생성하는 곳마다 있습니다.Error.

마지막으로, Chrome에서 곧 출시될 예정인 비동기는 매우 강력하고 약속을 반복하는 것입니다.

이러한 접근 방식은 어떻습니까?

async function example() {
  const arrayOfFetchPromises = [
    fetch('1.txt'),
    fetch('2.txt'),
    fetch('3.txt')
  ];

  // Regular iterator:
  for (const item of arrayOfFetchPromises) {
    console.log(item); // Logs a promise
  }

  // Async iterator:
  for await (const item of arrayOfFetchPromises) {
    console.log(item); // Logs a response
  }
}

에는 에는 .for-await각을서다에서 각 을 가져옵니다.array기다리죠 까지 해결 you 기다리죠 isn response even 까지 second in response yet the 해결' first responses the you if get get ll but order the ' correct , the ready ' t always ll 2두 번째 응답이 아직 준비되지 않았더라도 첫 번째 응답이 나오겠지만, 항상 정확한 순서대로 응답이 나올 것입니다.한된을히절할수다여수e할eeuygedn한n절된히을여e.catch:) 하지만 이러한 패턴은 처리되지 않은 거부반응을 일으키기 쉬운 것으로 알려져 있습니다.항상 있습니다.Promise.all.. ◦.모든 버전:

const [value1, value2] = await Promise.all([getValue1Async(), getValue2Async()]);

이 툴들 중 몇 가지를 확인해 보는 것도 좋습니다. iter-tools.

언급URL : https://stackoverflow.com/questions/30290567/es6-generators-poor-stack-trace-from-iterator-throwerr