[javascript] console.log () 비동기 또는 동기화?
현재 Trevor Burnham의 Async Javascript 를 읽고 있습니다. 이것은 지금까지 훌륭한 책이었습니다.
그는이 스 니펫과 console.log가 Safari 및 Chrome 콘솔에서 ‘비동기’라고 말합니다. 불행히도 나는 이것을 복제 할 수 없습니다. 다음은 코드입니다.
var obj = {};
console.log(obj);
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
이것이 비동기 적이라면 결과가 책 결과가 될 것으로 예상합니다. console.log ()는 모든 코드가 실행될 때까지 이벤트 큐에 넣은 다음 실행되고 bar 속성을 갖게됩니다.
동 기적으로 실행되고 있지만 나타납니다.
이 코드를 잘못 실행하고 있습니까? console.log는 실제로 비동기입니까?
답변
console.log
표준화되지 않았으므로 동작이 정의되지 않았으며 개발자 도구의 릴리스마다 쉽게 변경할 수 있습니다. 곧 제 답변처럼 귀하의 책은 구식 일 가능성이 있습니다.
우리 코드에서는 console.log
비동기 여부와 상관없이 어떠한 종류의 콜백도 제공하지 않습니다. 전달하는 값은 항상 함수를 호출 할 때 참조되고 계산됩니다.
우리는 그때 무슨 일이 일어나는지 실제로 알지 못합니다 (좋습니다. Firebug, Chrome Devtools 및 Opera Dragonfly는 모두 오픈 소스이기 때문에 가능합니다). 콘솔은 기록 된 값을 어딘가에 저장해야하며 화면에 표시합니다. 렌더링은 확실하게 비동기식으로 발생하며 (속도 제한 업데이트로 제한됨) 콘솔에 로깅 된 개체와의 향후 상호 작용 (예 : 확장 개체 속성)이 마찬가지입니다.
따라서 콘솔은 로그 한 변경 가능한 객체를 복제 (직렬화)하거나 참조를 저장할 수 있습니다. 첫 번째는 깊고 큰 물체에서는 잘 작동하지 않습니다. 또한 적어도 콘솔의 초기 렌더링은 아마도 객체의 “현재”상태를 보여줄 것입니다. 즉, 로그인했을 때의 상태를 보여줄 것입니다 Object {}
.
그러나 속성을 추가로 검사하기 위해 개체를 확장하면 콘솔에 개체 및 해당 속성에 대한 참조 만 저장 될 가능성이 높으며 지금 표시하면 현재 (이미 변경된) 상태가 표시됩니다. 를 클릭 +
하면 bar
예제 에서 속성 을 볼 수 있습니다 .
다음 은 “수정”을 설명하기 위해 버그 보고서 에 게시 된 스크린 샷입니다 .
따라서 일부 값은 기록 된 후 오랫동안 참조 될 수 있으며 이러한 값의 평가는 다소 느 립니다 ( “필요할 때”). 이 불일치의 가장 유명한 예 는 Chrome의 JavaScript 콘솔이 배열 평가에 대해 게으른가요? 라는 질문에서 처리됩니다 .
해결 방법은 객체의 직렬화 된 스냅 샷을 항상 기록하는 것 console.log(JSON.stringify(obj))
입니다 ( 예 : . 그러나 이것은 원형이 아닌 작은 물체에만 작동합니다. Safari에서 console.log의 기본 동작을 어떻게 변경할 수 있습니까?를 참조하십시오 . .
더 나은 솔루션은 디버깅에 중단 점을 사용하는 것입니다. 여기서 실행이 완전히 중지되고 각 지점에서 현재 값을 검사 할 수 있습니다. 직렬화 가능하고 변경 불가능한 데이터에만 로깅을 사용하십시오.
답변
이것은 실제로 질문에 대한 답은 아니지만이 게시물을 우연히 발견 한 사람에게는 유용 할 수 있으며 댓글을 달기에는 너무 길었습니다.
window.console.logSync = (...args) => {
try {
args = args.map((arg) => JSON.parse(JSON.stringify(arg)));
console.log(...args);
} catch (error) {
console.log('Error trying to console.logSync()', ...args);
}
};
이것은의 의사 동기 버전을 생성 console.log
하지만 수락 된 답변에서 언급 한 것과 동일한 경고가 있습니다.
현재 대부분의 브라우저 console.log
는 어떤 방식 으로든 비동기식 인 것처럼 보이므로 특정 시나리오에서 이와 같은 기능을 사용하는 것이 좋습니다.
답변
console.log를 사용하는 경우 :
a = {}; a.a=1;console.log(a);a.b=function(){};
// without b
a = {}; a.a=1;a.a1=1;a.a2=1;a.a3=1;a.a4=1;a.a5=1;a.a6=1;a.a7=1;a.a8=1;console.log(a);a.b=function(){};
// with b, maybe
a = {}; a.a=function(){};console.log(a);a.b=function(){};
// with b
첫 번째 상황에서 객체는 충분히 단순하므로 콘솔은이를 ‘문자열 화’하여 표시 할 수 있습니다. 그러나 다른 상황에서는 a가 ‘stringify’하기에는 너무 ‘복잡’하므로 콘솔은 대신 메모리 개체를 표시하고 예를 보면 b가 이미 a에 연결되어 있습니다.