कंसोल.लॉग () एसिंक्स या सिंक?


93

मैं वर्तमान में ट्रेवर बर्नहैम द्वारा Async जावास्क्रिप्ट पढ़ रहा हूं । यह अब तक की एक महान पुस्तक रही है।

वह इस स्निपेट और कंसोल के बारे में बात करता है। सफारी और क्रोम कंसोल में 'एसिंक्स' है। दुर्भाग्य से मैं इसे दोहरा नहीं सकता। यहाँ कोड है:

var obj = {}; 
console.log(obj); 
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};

यदि यह अनिवार्य था, तो मैं परिणाम को पुस्तकों के परिणाम होने का अनुमान लगाऊंगा। कंसोल.लॉग () को तब तक इवेंट कतार में रखा जाता है जब तक कि सभी कोड निष्पादित नहीं हो जाते, तब इसे चलाया जाता है और इसमें बार प्रॉपर्टी होती है।

ऐसा प्रतीत होता है कि यह समकालिक रूप से चल रहा है।

क्या मैं यह कोड गलत चला रहा हूं? क्या वास्तव में async सांत्वना है?


@thefourtheye: नहीं, इसलिए मुझे शायद अपनी टिप्पणी को हटा देना चाहिए।
कुकी राक्षस

1
मैंने देखा है कि यह क्रोम में होता है। यदि आप एक साधारण ऑब्जेक्ट को कंसोल करते हैं और फिर तुरंत ऑब्जेक्ट में कुछ बदलते हैं, तो console.log()हमेशा पूर्व मान नहीं दिखाता है। यदि आपके साथ ऐसा होता है, तो आपके आसपास जो भी कोशिश हो रही है console.log()उसे एक स्ट्रिंग में बदलना है, जो अपरिवर्तनीय है, इसलिए इस मुद्दे के अधीन नहीं है। इसलिए, अनुभव console.log()से कुछ async समस्याएँ संभवत: प्रक्रिया सीमाओं के पार डेटा से संबंधित हैं। यह इच्छित व्यवहार नहीं है, लेकिन console.log()आंतरिक रूप से कैसे काम करता है, इसके कुछ दुष्प्रभाव हैं (मैं व्यक्तिगत रूप से इसे बग समझूंगा)।
jfriend00


1
@bergi मुझे इस डूप को खोजने में सिर्फ 10 मिनट का समय लगा (हालाँकि मुझे सटीक नाम पता था), शायद इसलिए कि यह डुप्लीकेट है। क्या हम सिर्फ डुप्लिकेट स्वैप नहीं कर सकते, ताकि दूसरे को डुप्लिकेट किया जाए ...?
जोनास विल्म्स

1
@JonasWilms मैंने अब इस सवाल को फिर से खोल दिया है ( इतिहास देखें )। मुझे नहीं लगता कि वे एक-दूसरे के डुप्लिकेट हैं, मैं क्रोम के जावास्क्रिप्ट कंसोल का उपयोग कर ऐरे का मूल्यांकन कर रहा हूं ? विशेष रूप से एक सरणी को शामिल करने वाली समस्याओं के लिए विहित लक्ष्य के रूप में।
बेर्गी

जवाबों:


114

console.logमानकीकृत नहीं है, इसलिए व्यवहार को अपरिभाषित किया जाता है, और रिलीज़ से डेवलपर टूल के रिलीज़ तक आसानी से बदला जा सकता है। आपकी पुस्तक पुरानी होने की संभावना है, जैसा कि मेरा जवाब जल्द ही हो सकता है।

हमारे कोड के लिए, यह कोई अंतर नहीं console.logहै कि क्या यह async है या नहीं, यह किसी भी प्रकार की कॉलबैक या तो प्रदान नहीं करता है; और आपके द्वारा पास किए गए मान हमेशा फ़ंक्शन को कॉल करते समय संदर्भित और गणना किए जाते हैं।

हम वास्तव में नहीं जानते हैं कि तब क्या होता है (ठीक है, हम कर सकते हैं, क्योंकि फायरबग, क्रोम देवटूल और ओपेरा ड्रैगनफ्लाई सभी खुले स्रोत हैं)। कंसोल को लॉग किए गए मानों को कहीं स्टोर करने की आवश्यकता होगी, और यह उन्हें स्क्रीन पर प्रदर्शित करेगा। रेंडरिंग सुनिश्चित करने के लिए एसिंक्रोनस रूप से घटित होगी (दर-सीमा अपडेट के लिए थ्रॉटल किया जा रहा है), क्योंकि कंसोल में लॉग की गई वस्तुओं के साथ भविष्य के इंटरैक्शन (जैसे ऑब्जेक्ट ऑब्जेक्ट का विस्तार करना) होगा।

तो कंसोल या तो क्लोन (अनुक्रमित) कर सकता है जो आप द्वारा लॉग किए गए उत्परिवर्तनीय वस्तुओं को, या यह उनके संदर्भों को संग्रहीत करेगा। पहले वाला गहरी / बड़ी वस्तुओं के साथ अच्छा काम नहीं करता है। इसके अलावा, कम से कम कंसोल में प्रारंभिक रेंडरिंग संभवतः ऑब्जेक्ट की "वर्तमान" स्थिति को दिखाएगा, अर्थात जब यह लॉग इन हुआ - तो आपके उदाहरण में आप देखेंगे Object {}

हालाँकि, जब आप ऑब्जेक्ट को उसके गुणों का निरीक्षण करने के लिए आगे बढ़ाते हैं, तो यह संभावना है कि कंसोल ने केवल आपके ऑब्जेक्ट और उसके गुणों का संदर्भ संग्रहीत किया होगा, और अब उन्हें प्रदर्शित करना उनकी वर्तमान (पहले से उत्परिवर्तित) स्थिति को दिखाएगा। यदि आप पर क्लिक करते हैं +, तो आपको barअपने उदाहरण में संपत्ति देखने में सक्षम होना चाहिए ।

यहाँ एक स्क्रीनशॉट है जो बग रिपोर्ट में उनके "फिक्स" को समझाने के लिए पोस्ट किया गया था :

इसलिए, कुछ मानों को लॉग किए जाने के लंबे समय बाद संदर्भित किया जा सकता है, और इनका मूल्यांकन बल्कि आलसी है ("जब आवश्यक हो")। इस विसंगति का सबसे प्रसिद्ध उदाहरण प्रश्न में संभाला है क्रोम के जावास्क्रिप्ट कंसोल सरणियों के मूल्यांकन के बारे में आलसी है?

एक वर्कअराउंड यह सुनिश्चित करना है कि हमेशा अपनी वस्तुओं के क्रमबद्ध स्नैपशॉट लॉग करें, जैसे कि करके console.log(JSON.stringify(obj))। यह गैर-परिपत्र और बल्कि छोटी वस्तुओं के लिए काम करेगा, हालांकि। यह भी देखें कि मैं सफारी में कंसोल.लॉग के डिफ़ॉल्ट व्यवहार को कैसे बदल सकता हूं?

बेहतर समाधान डिबगिंग के लिए ब्रेकपॉइंट्स का उपयोग करना है, जहां निष्पादन पूरी तरह से बंद हो जाता है और आप प्रत्येक बिंदु पर वर्तमान मानों का निरीक्षण कर सकते हैं। केवल क्रमिक और अपरिवर्तनीय डेटा के साथ लॉगिंग का उपयोग करें।


2
मुझे कंसोल के साथ एक ही मुद्दा था। async नहीं होना। JSON.stringify का उपयोग करके इसे मेरे लिए तय किया गया
रूसी

2019 तक, क्या हम कह सकते हैं कि console.logक्रोम में अभी भी अतुल्यकालिक है क्योंकि यह 8 साल का था (देखें stackoverflow.com/questions/7389069/… ), केवल एक चीज जो बदलती है वह यह है कि अब क्रोम संदर्भ वस्तु के स्नैपशॉट को आउटपुट करता है आपके द्वारा कॉल किए जाने का समय console.log(यदि आप लॉग की गई वस्तु का विस्तार करते हैं, तो आप उसके अंतिम गुण और मान देखेंगे, जो आपके द्वारा किए गए म्यूटेशन ऑपरेशन के बाद है console.log), या console.logवास्तव में सिंक्रोनस है?
टोनिक्स

@tonix हां, मेरे उत्तर में दिए गए कारणों के कारण इस व्यवहार को बदलने की संभावना नहीं है। यह बग नहीं है, यह सिर्फ एक इंटरैक्टिव डिबगर / इंस्पेक्टर कैसे काम करता है।
बर्गी

यदि आप JSON.parse(JSON.stringify(obj))टिप्पणी के रूप में उपयोग करते हैं तो यहां आपको एक स्ट्रिंग के बजाय ऑब्जेक्ट फॉर्म में एक स्नैपशॉट मिलता है।
विल्ट

टीएल; डीआर.वे रास्ता टीएल
रिक

2

यह वास्तव में सवाल का जवाब नहीं है, लेकिन यह किसी ऐसे व्यक्ति के लिए उपयोगी हो सकता है जो इस पोस्ट पर ठोकर खा गया, और यह एक टिप्पणी में बहुत लंबा था:

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किसी तरह से अतुल्यकालिक हैं, आप कुछ परिदृश्यों में इस तरह के फ़ंक्शन का उपयोग करना चाह सकते हैं।


0

कंसोल का उपयोग करते समय।

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

पहली स्थिति में वस्तु काफी सरल होती है, इसलिए सांत्वना 'स्ट्रिंग' कर सकती है और फिर आपके सामने मौजूद होती है; लेकिन अन्य स्थितियों में, एक 'जटिल' करने के लिए 'कठोर' है, इसलिए कंसोल आपको इसके बजाय मेमोरी ऑब्जेक्ट में दिखाएगा, और हां, जब आप इसे देखते हैं तो बी पहले ही ए से जुड़ा हुआ है।


मुझे पता है कि यह प्रश्न 3 साल पुराना है, लेकिन अभी मैं एक ही समस्या में चल रहा हूं - ऑब्जेक्ट को क्रमबद्ध करना मेरे लिए काम नहीं करता है क्योंकि यह बहुत जटिल है। मैं एक डेटा को एक्सेस करने की कोशिश कर रहा एक घटना को पकड़ रहा हूं, लेकिन किसी तरह यह कोड में कोई डेटा नहीं है, लेकिन कंसोल में। इसमें डेटा है।
स्कीक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.