2024.10.10 기록

더 이상의 지연은 없다·2024년 10월 10일
0

모브박스 - 유튜브 api / then, async-await, setTimeout

const YOUTUBE_API_KEY = 'AAAAAAAAAAA';
let [youtubeId, setYoutubeId] = useState([]);
const youtubeMv = dailyBoxOffice.slice(0, 3);

// youtubeMv = ['베테랑2', '트랜스포머 ONE', '사랑의 하츄핑'];

useEffect(() => {
	dataFetch4(dailyBoxOffice, movieDate)
        
	youtubeMv.forEach((movie) => {
    	axios.get(
       `https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=${movie} 예고편&type=video&key=${YOUTUBE_API_KEY}`
    )
        .then((res) => {
          setYoutubeId(res.data.items);
      })
      .catch((err) => {
        console.error(`Error fetching trailer for ${movie}: `, err);
		});
	})
}, [dailyBoxOffice])

console.log('youtubeId 검색결과', youtubeId);

console.log('youtubeId 검색결과', youtubeId);

'youtubeId 검색결과',[{..}]
'youtubeId 검색결과',[{..}]
'youtubeId 검색결과',[{..}]

youtubeId 값이 다 따로따로 나온다.
그러니 youtubeId.map을 해도 li는 하나만 출력된다.

<ul>
	{
    youtubeId.map((obj, index)=>(
    	<li k={index}>
			<Link className="view_box" href={`https://www.youtube.com/watch?v=${obj.id.videoId}`} target="_blank">
      
      			<div className="thumb_box">
        			<Image src={obj.snippet.thumbnails.medium.url}
        			width={320} height={180}
        			alt="트레일러 썸네일" priority />
      			</div>
      
    		</Link>
		</li>
    ))
	}

비동기 작업 thenasync/await 차이
then

  • 체인형 비동기 처리
  • .then()과 .catch()를 연달아 붙여 비동기 흐름을 제어
  • .catch()로 에러 처리

async / await

  • Promise 기반 비동기 처리
  • 직관적인 구문으로 가독성 좋음
  • sync는 항상 프로미스를 반환, await은 프로미스가 해결될 때까지 기다림
  • try / catch로 에러 처리

동기(synchronous)란,
어떤 작업을 실행할 때 그 작업이 끝나기를 기다리는 방식

비동기(asynchronous)란,
어떤 작업을 실행할 때 그 작업이 완료되지 않더라도
다음 코드를 실행하는 방식을 의미한다.
(async와 await를 사용하면 비동기 코드를 동기 코드처럼 작성할 수 있어, 가독성이 좋아지고 에러 처리가 간단해진다.

ex.

function ziyeon() {
    for (let i = 0; i < 10000; i++) {
        console.log(1);
    }
    console.log(2);
}

동기 코드는 가장 먼저 바로 실행된다.
콘솔에 2가 찍히려면 1만 번의 1이 찍힐 때까지 기다려야 한다.
출처: https://trustmitt.tistory.com/85 [kohigowild:티스토리]


ex.

function ziyeon() {
    for (let i = 0; i < 10000; i++) {
        setTimeout(() => {
            console.log(1); // 비동기처리
        }, 0);
    }
    console.log(2);
}
ziyeon();

setTimeout 을 사용하여 콘솔 2먼저 찍히고 콘솔 1이 나중에 찍힌다.
즉, for루프가 도는동안 setTimeout은 비동기처리 된다.


function ziyeon() {
    new Promise((resolve, reject) => {
        try {
            for (let i = 0; i < 10000; i++) {
                console.log(1);
            }

            resolve(); 
        } catch (error) {
            reject('작업 실패!');
        }
    })
    .then(() => {
        console.log(2);  // 비동기처리
    })
    .catch((error) => {
        console.error(error);
    });
}

ziyeon();

비동기 처리시 사용되는 메서드 new Promise()
인자값으로는 resolve/성공, reject/실패

try, catch 블럭으로 에러를 감지하고
for 루프가 문제없이 성공한다면 resolve() 호출하고,
비동기처리된 .then()이 실행한다.
작업 실패시 reject() 호출하여 .catch()가 실행한다.


async function ziyeon() {
    console.log('1');

    await new Promise((resolve) => setTimeout(resolve, 0)); 
    console.log('3'); // 비동기
}

ziyeon();
console.log('2');

await는 반드시 async 함수 내부에서만 사용해야 한다.
콘솔1은 동기처리로 인해 바로 실행된다.
await로 인해 setTimeout()로 비동기처리 된 콘솔3은 실행대기하는동안
콘솔2 먼저 동기처리 되어 실행되고, 후에 콘솔3이 실행한다.

*여기서 0은 '0초 후 실행'이 아닌 다음 이벤트 루트로 코드를 미루는것임


    useEffect(() => {
        dataFetch4(dailyBoxOffice, movieDate)

        const fetchYoutubeTrailers = async () => {
            try {
                const promises = youtubeMv.map((movie) =>
                    axios.get(
                        `https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=${movie} 예고편&type=video&key=${YOUTUBE_API_KEY}`
                    )
                );

                const responses = await Promise.all(promises);  //모든 요청 기다림

                const videoId = responses.map((response) => response.data.items[0]);
                setYoutubeId(videoId);
                console.log(videoId, 'videoId')
                
            } catch (error) {
                console.error('Error fetching YouTube trailers:', error);
            }
        };

        fetchYoutubeTrailers();
    }, [dailyBoxOffice])

    console.log('youtubeId 검색결과', youtubeId);

fetchYoutubeTrailers 함수를 async로 비동기처리를 걸어놓고
promises에 영화에 대한 axios 요청 배열 생성하고
await로 axios의 실행이 완료 될때까지 기다린다.
만약 1개라도 실행이 안됐다면 catch 에러 블록으로 넘어간다.

profile
어제보단 나은 지연이의 오늘

0개의 댓글