[javascript] 동기 iterable과 함께 await…

MDN에 따르면 for await...of 두 가지 사용 사례가 있습니다.

for await...of명령문은 비동기 반복 가능 오브젝트와 동기화 반복 가능 오브젝트를 반복하는 루프를 작성합니다.

나는 이전을 알고 있었다 : async iterables using Symbol.asyncIterator. 그러나 나는 이제 후자에 관심이있다 : 동기 iterables.

다음 코드는 동기식 iterable-약속 배열을 반복합니다. 각 약속의 성취에 대한 절차를 막는 것으로 보입니다.

async function asyncFunction() {
    try {
        const happy = new Promise((resolve)=>setTimeout(()=>resolve('happy'), 1000))
        const sad = new Promise((_,reject)=>setTimeout(()=>reject('sad')))
        const promises = [happy, sad]
        for await(const item of promises) {
            console.log(item)
        }
    } catch (err) {
        console.log(`an error occurred:`, err)
    }
}

asyncFunction() // "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)

이 동작은 아래 표시된 논리에 따라 차례대로 각 약속을 기다리는 것과 같습니다. 이 주장이 맞습니까?

이 코드 패턴이 암시 적 거부 와이어 업 함정이 있기 때문에 물어 Promise.allPromise.allSettled피하고을하고,이 패턴이 명시 적으로 언어에 의해 지원 될 것이라고 나에게 이상한 것 같다.



답변

예, 이상합니다. 이렇게하면 안됩니다. 약속의 배열을 반복하지 마십시오 . 언급 한 처리되지 않은 거부 문제가 발생합니다 .

왜 이것이 언어로 지원됩니까? 조잡한 약속 의미론을 계속합니다.

제안서 의이 부분을 논의하는 문제에 대한이 의견 에서 정확한 추론을 찾을 수 있습니다 .

Symbol.iterator현재 Promise 시맨틱은 동기화 사물을 비동기식으로 사용하도록 허용하는 것에 관한 것이므로 다시 돌아 가야한다고 생각합니다 . 이것을 “느슨 함”이라고 부를 수 있습니다. 위의 @groundwater의 논리를 따르지
만, 더 자세히 병렬을 철자하고 싶습니다.

“체인”시맨틱 .then은 이것에 관한 것입니다. 약속 .then또는 스칼라 값을 반환 할 수 있습니다 . 모두 동일합니다. 당신은 전화
Promise.resolve약속에 뭔가를 포장하지,하지만 약속에 캐스팅 뭔가 – 당신이 뭔가 – 또는 – 다른이있을 때 비동기 값을 가져옵니다.

의 의미 async와는 await물론 정치 못한 것에 대해 모두. await비동기 함수에서 Promise가 아닌 표현식을 때릴 수 있으며 작업 대기열에 대한 제어 권한을 얻는 것을 제외하고는 모든 방식이 정확하게 동일하게 작동합니다. 마찬가지로, 결과가있는 한 async
원하는대로 “방어 적으로”넣을 수 await있습니다. 약속을 반환하는 함수가 있다면 무엇이든! 그 async기능을 만들 수
있고, 사용자 관점에서는 아무런 변화가 없습니다 (기술적으로 다른 Promise 객체를 가져와도).

비동기 반복자와 생성기는 같은 방식으로 작동해야합니다. 실수로 약속이 아닌 값을 기다리는 것처럼 합리적인 사용자는 yield*비동기 생성기 내에서 동기화 반복기 를 사용할 수있을 것으로 기대합니다 . for await사용자가 방어적인 방식으로 루프를 표시하는 경우 루프가 비동기 반복자를 얻을 수 있다고 생각하면 루프도 마찬가지로 “작동”해야합니다.

이러한 모든 유사점을 깨뜨리는 것이 큰 일이라고 생각합니다. 비동기 반복자를 덜 인체 공학적으로 만듭니다. 다음에 비동기 생성기 / 반복기가 TC39의 안건에 등장 할 때 이에 대해 논의 해 봅시다.


답변

sad약속은 하지 않습니다 되는 await코드의 요구에 대기 완료하는 것을 – 그것이 실패했을 때 ED happy가에 기다릴 시작하기 전에 sad. sad약속은 전에 실패 happy해결합니다. ( Promise.all이 사용 사례에 더 적합한 도구입니다)


답변