사진에 나와있는 코드를 실행하면 출력 순서가 어떻게 될까?
1.start!
2.어떤 값이 담긴 result
3.End
이런 순으로 출력 될거라고 생각 할 수 있다.
그러나 막상 코드를 실행해보면 우선 Start와 End가 먼저 출력되고 그 후에 어떤 값이 들어있는 result가 출력되는 것을 볼 수 있다.
바로 이렇게 한번 시작된 작업이 완료되기전에 바로 다음 코드로 실행이 넘어가게 되어 나중에 (then파라미터에 있는)콜백이 실행되어 마무리 되는 것을 비동기 실행이라고 한다.
비동기 실행을 하면 서버와 통신을 하여 response를 받아야 끝나는 작업과 같이 이러한 작업들 실행 시켜놓고 서버가 response를 보내줄때까지 기다리지 않고 다른 코드를 실행하여 시간을 절약할 수 있다.
그리고 이러한 비동기 실행에 관한 개념을 더욱 자세히 알려면 fetch함수와 then메서드가 리턴하는 promise객체도 알아야 한다.
promise객체는 어떤 작업에 관한 '상태 정보'를 나타내는 객체이다.
그래서 fetch함수가 리턴한 promise객체를 보면 지금 하고 있는 작업이 실패했는지 성공했는지 알 수 있다.
일단 맨처음 fetch함수가 리턴한 promise객체는 pending상태이다.
그리고 그 후 response를 정상적으로 잘 받으면 fulfilled상태가 되고
잘 받지 못하면 rejected상태가 된다.
여기서 promise객체가 fulfilled상태가 되면 그 작업성공 결과값을 가지게 된다.
여기서는 작업의 성공결과가 response객체가 될 것이다.
또 만약에 인터넷 문제 등 여러가지 문제로 인해 작업 실행이 실패하게 되면 실패한 정보를 promise객체에 담아 보낸다.
then메소드는 promise객체의 상태가 pending에서 fullfilled가 될 때 실행할 콜백을 등록하는 메소드이다.
아까 promise객체가 fulfilled상태가 되면 작업 성공 결과를 담는다고 했는데 그 성공 결과는 서버가 보내준 response이다
이 response를 then메소드의 콜백의 첫번째 파라미터로 전달해준다.
서버에서 받은 response를 자바스크립트의 객체형태로 만든 결과를 형광박스에 담는다
이런식으로 끊임없이 then메소드를 이어 붙일 수 있다.
그런데 분명히 then메소드는 promise객체의 메소드라고 했는데 어떻게 계속 then메소드를 연속적으로 사용할 수 있는걸까?
🔥그것은 바로 then메소드가 다시 새로운 promise객체를 리턴하기 때문이다.
이러한 것을 바로 프로미스체인닝(Promise Chaining)이라고한다.
또 한가지 중요한 사실이 있는데
then메소드는 처음에 pending상태의 promise객체를 리턴한다.
그러다가 fetch함수에서 보냈던 request에대한 response를 잘 받으면 then메소드 내에 콜백이 실행되고 값을 리턴할 것이다.
콜백의 리턴값은 (then메소드가 pending상태로 리턴한)promise객체에 영향을 주는데 콜백의 리턴값의 종류에 따라 (then메소드가 pending상태로 리턴한)promise객체가 받는 영향도 달라진다.
🔥then메소드가 리턴한 promise객체는 콜백이 리턴한 promise객체와 동일한 상태와 결과를 갖게 된다.
콜백이 리턴한 promise객체가 fulfilled가 되면 then메소드가 리턴한 promise객체도 fulfilled가 되고 같은 작업 성공 결과를 같는 것이다.
콜백이 promise객체가 아닌 다른 값을 리턴하면 then메소드가 리턴한 promise객체는 fulfilled상태가 되고 콜백이 리턴한 작업 성공 결과를 가진다.
콜백이 실행도중에 만약 error가 발생한다면 이 콜백을 파라미터로 가진 then메소드가 리턴하는 promise객체는 콜백 실패한 이유가 담긴 error객체를 가지고 rejected 상태가 된다.
undefined값을 then메소드가 리턴한 promise객체가 전달 받는다.
이전 promise객체를 then메소드가 리턴한 promise객체가 전달 받는다.
위 두 사진의 코드를 보고 차이점이 보이나?
그렇다 분명 코드상의 차이점은 존재한다. 그러나 동작은 같게 한다.
콜백이 promise객체를 리턴하면 then메소드가 리턴하는 promise객체와 동일한 상태와 결과를 가지기 때문에 이러한 성질을 잘 이용하면 콜백안에 then메소드를 쓸 필요가 없다.
어차피 두번째 then메소드에서 fetch함수를 이용해 promise객체를 리턴하기때문에 그냥 then메소드를 붙여주기만 하면 된다.
그렇다면 이렇게 then메소드를 연속적으로 사용하는 promise Chanining은 왜 쓰는 것 일까?
🔥바로 순차적으로 비동기 작업을 처리하기 위해서이다.
이 말을 조금 더 풀어서 설명하자면 특정 사용자의 정보를 먼저 알기위해서는 우선 사용자들의 정보를 불러와야한다.
사용자들의 정보를 불러오고 그중에서 특정 사용자를 선택하고 그 다음 특정 사용자를 조회해야하기 때문에 반드시 순차적인 작업이 필요하다.
바로 이럴때 promise Chaining을 쓰는 것이다.
그런데 간혹 promise객체의 상태가 fulfilled상태가 되는 것이 아니라 rejected상태가 될 수도 있다.
이에 대비하기 위해 promise객체가 rejected상태가 되었을때 실행할 콜백을 등록해놓을 수 있다.
error를 대비한 콜백은 then메소드의 두번째 파라미터값에 등록해놓으면 된다.
그래서 어떤 이유들로 인해서 제데로 된 작업이 성공하지 못하면 fetch함수가 리턴하는 promise객체는 rejected상태가 되고 실패와 관련된 error객체를 작업 실패 결과로 가지게 된다.
그래서 작업 실패 결과는 then메소드의 두번째 콜백 파라미터로 전달이 되고 (인터넷 연결을 끊어 강제로 rejected가 되게 만들고)출력을 해보면 error가 뜨는 것을 볼 수있다.