맨 뒤에것이 맨 앞에 나온다.
Promise.resolve('foo')
// 1. "foo"를 받고 "bar"를 추가한 다음 그 값으로 이행하여 다음 then에 넘겨줌
.then(function(string) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
string += 'bar';
resolve(string);
}, 1000);
});
})
// 2. "foobar"를 받고 그대로 다음 then에 넘겨준 뒤,
// 나중에 콜백 함수에서 가공하고 콘솔에 출력
.then(function(string) {
setTimeout(function() {
string += 'baz';
console.log(string);
}, 1000)
return string;
})
// 3. 이 부분의 코드는 이전의 then 블록 안의 (가짜) 비동기 코드에서
// 실제로 문자열을 가공하기 전에 실행됨
.then(function(string) {
console.log("마지막 Then: 앗... 방금 then에서 프로미스 만들고 반환하는 걸 까먹어서 " +
"출력 순서가 좀 이상할지도 몰라요");
// 'baz' 부분은 setTimeout 함수로 비동기적으로 실행되기 때문에
// 이곳의 string에는 아직 'baz' 부분이 없음
console.log(string);
});
// 로그 출력 결과 (순서대로):
// 마지막 Then: 앗... 방금 then에서 프로미스 만들고 반환하는 걸 까먹어서 출력 순서가 좀 이상할지도 몰라요
// foobar
// foobarbaz
3번째 then이 먼저나온다.
세번째는 그냥함수 첫번째는 동기 두번째는 비동기
이 코드의 동작을 이해하려면 JavaScript의 비동기 처리와 Promise의 동작 방식을 이해해야 합니다.
첫 번째 .then 블록에서는 new Promise를 반환하고 있습니다. 이 Promise는 setTimeout 함수 안에서 resolve가 호출되기 때문에, setTimeout에 지정된 시간(1초)이 지난 후에 이행됩니다.
두 번째 .then 블록에서는 비동기적으로 실행되는 setTimeout 함수 안에서 문자열을 가공하고 있지만, 그 결과를 반환하는 Promise를 만들지 않고 있습니다. 즉, 이 블록의 반환 값은 setTimeout 함수가 실행되기 전에 결정되고, 이행된 상태의 Promise로 다음 .then 블록으로 넘어갑니다.
그래서, 세 번째 .then 블록은 두 번째 .then 블록에서 반환한 Promise가 이미 이행된 상태이므로 즉시 실행되고, 그 결과가 먼저 출력됩니다. 그리고 setTimeout 함수가 실행되면서 두 번째 .then 블록에서 가공한 문자열이 나중에 출력되는 것입니다.
따라서 출력 순서는 다음과 같습니다:
세 번째 .then 블록: "마지막 Then: 앗... 방금 then에서 프로미스 만들고 반환하는 걸 까먹어서 출력 순서가 좀 이상할지도 몰라요"
세 번째 .then 블록: "foobar" (두 번째 .then 블록에서 반환한 문자열)
두 번째 .then 블록: "foobarbaz" (비동기적으로 가공한 문자열)
비동기 코드를 다룰 때는 이렇게 동작 순서가 복잡해질 수 있으므로, 코드의 동작을 정확히 예측하려면 Promise와 비동기 처리에 대한 깊은 이해가 필요합니다.
User
첫번째 then이랑 두번째 then이랑 뭐가달라?
ChatGPT
첫 번째 .then과 두 번째 .then은 Promise가 처리되는 방식에서 차이가 있습니다.
첫 번째 .then에서는 Promise를 반환하고 있습니다. 이 Promise는 setTimeout 함수 안에서 resolve가 호출되기 때문에, setTimeout에 지정된 시간(1초)이 지난 후에 이행됩니다. 따라서 이 Promise가 이행되기 전까지는 다음 .then 블록이 실행되지 않습니다.
하지만 두 번째 .then에서는 비동기적으로 실행되는 setTimeout 함수 안에서 문자열을 가공하고 있지만, 그 결과를 반환하는 Promise를 만들지 않고 있습니다. 이 함수는 비동기적으로 실행되지만, Promise를 반환하지 않기 때문에 이행 상태를 Promise 체인에 전달하지 않습니다. 즉, 이 블록의 반환 값은 setTimeout 함수가 실행되기 전에 결정되고, 이행된 상태의 Promise로 다음 .then 블록으로 넘어갑니다.
그래서 세 번째 .then 블록은 두 번째 .then 블록에서 반환한 Promise가 이미 이행된 상태이므로 즉시 실행되고, 그 결과가 먼저 출력됩니다.
이런 차이는 Promise와 비동기 처리의 동작 방식에 기반하며, 비동기 코드를 작성할 때는 이런 동작을 잘 이해하고 있어야 합니다.
이건 순서가 왜이러냐....
var p2 = new Promise(function(resolve, reject) {
resolve(1);
});
p2.then(function(value) {
console.log(value); // 1
return value + 1;
}).then(function(value) {
console.log(value + ' - 동기적으로 짜도 돌아감');
});
console.log("이게머지");
p2.then(function(value) {
console.log('haha');
console.log(value); // 1
console.log('haha');
});
Promise의 동작 방식과 JavaScript의 이벤트 루프에 대해 이해하면 이 질문에 답변할 수 있습니다.
Promise의 .then 메소드는 항상 비동기적으로 동작합니다. 콜백 함수는 즉시 실행되지 않고, 대신 이벤트 루프의 마이크로태스크 큐에 추가됩니다. 마이크로태스크 큐의 콜백 함수는 현재 실행 중인 코드가 모두 완료된 후에 실행됩니다.
이 코드에서는 p2가 이미 이행된 상태의 Promise이므로, p2.then()을 호출하면 콜백 함수가 즉시 마이크로태스크 큐에 추가됩니다. 그러나 이 콜백 함수는 현재 실행 중인 코드가 모두 완료된 후에 실행되므로, "이게머지"가 먼저 출력됩니다.
그 다음에 이벤트 루프는 마이크로태스크 큐에서 가장 먼저 추가된 콜백 함수를 실행합니다. 이 코드에서 첫 번째 p2.then()의 첫 번째 콜백 함수와 두 번째 p2.then()의 콜백 함수가 거의 동시에 큐에 추가됩니다. JavaScript는 단일 스레드로 동작하므로, 두 콜백 함수가 동시에 실행되는 것은 불가능합니다. 따라서 두 콜백 함수의 실행 순서는 JavaScript 엔진의 내부 동작 방식에 따라 결정됩니다.
이 경우에는 두 번째 p2.then()의 콜백 함수가 먼저 실행되었음을 알 수 있습니다. 그 다음에 첫 번째 p2.then()의 두 번째 콜백 함수가 실행됩니다. 이 콜백 함수는 첫 번째 콜백 함수에서 반환된 값을 사용하므로, 첫 번째 콜백 함수가 완료된 후에만 실행될 수 있습니다.
따라서 출력 순서는 다음과 같습니다:
"이게머지"
"1"
"haha"
"1"
"haha"
"2 - 동기적으로 짜도 돌아감"
이렇게 Promise와 이벤트 루프의 동작 방식을 이해하면 비동기 코드의 동작 순서를 예측할 수 있습니다.
죄송합니다, 제 설명이 혼란을 준 것 같습니다. 올바른 순서로 다시 설명하겠습니다.
이 경우, .then 메소드는 다음과 같은 순서로 실행됩니다:
p2 프로미스가 resolve되면서 첫 번째 then 메소드의 첫 번째 콜백 함수가 마이크로태스크 큐에 추가됩니다. 이 콜백 함수는 console.log(value);와 return value + 1;를 실행합니다.
첫 번째 then 메소드의 두 번째 콜백 함수는 첫 번째 콜백 함수가 return한 값을 받아서 마이크로태스크 큐에 추가됩니다. 이 콜백 함수는 console.log(value + ' - 동기적으로 짜도 돌아감');을 실행합니다.
두 번째 then 메소드의 콜백 함수가 마이크로태스크 큐에 추가됩니다. 이 콜백 함수는 console.log('haha');, console.log(value);, console.log('haha');를 실행합니다.
이로 인해 출력 순서는 다음과 같습니다:
"1" - 첫 번째 then 메소드의 첫 번째 콜백 함수에서 출력됩니다.
"haha" - 두 번째 then 메소드의 콜백 함수에서 출력됩니다.
"1" - 두 번째 then 메소드의 콜백 함수에서 출력됩니다.
"haha" - 두 번째 then 메소드의 콜백 함수에서 출력됩니다.
"2 - 동기적으로 짜도 돌아감" - 첫 번째 then 메소드의 두 번째 콜백 함수에서 출력됩니다.
JavaScript는 단일 스레드로 동작하며, 이벤트 루프를 통해 비동기 동작을 처리합니다. 이벤트 루프는 마이크로태스크 큐에 있는 콜백 함수를 순서대로 처리합니다. 따라서 .then 메소드의 콜백 함수는 등록된 순서대로 실행됩니다. 하지만 이 경우에는 첫 번째 then 메소드의 두 번째 콜백 함수가 첫 번째 콜백 함수가 return한 값을 기다려야 하므로, 두 번째 then 메소드의 콜백 함수가 먼저 실행됩니다. 이로 인해 출력 순서가 위와 같이 나타납니다.
댓글 영역