摘要:問題出現在循環體內的回調函數,用一個很簡單的例子舉例此例子忽略了等待回調函數完成的實現不實現這個會導致作為單個文件運行的時候,還沒獲得結果就退出了,在中的提供了相關功能這個地址的作用是返回了請求的對象,形如但實際上,由于回調函
問題出現在循環體內的回調函數,用一個很簡單的例子舉例:
for x in xrange(3): print "requests begin:%s"%x def callback(respon): print x print respon.body client.fetch("http://httpbin.org/get?x=%s" % x, callback)
此例子忽略了等待回調函數完成的wait實現(不實現這個會導致作為單個文件運行的時候,還沒獲得結果就退出了),在tornado.testing中的AsyncTestCase提供了相關功能
httpbin.org/get這個地址的作用是返回了請求的json對象,形如:
{ "args": { "x": "0" }, "headers": { "Accept-Encoding": "gzip", "Connection": "close", "Host": "httpbin.org", "X-Request-Id": "95df3c15-7ed0-4a6d-830d-fb9629e66515" }, "origin": "192.81.129.91", "url": "http://httpbin.org/get?x=0" }
但實際上,由于回調函數特殊的特性:訪問閉包內局部變量的當前值。易知,在第一個請求
http://httpbin.org/get?x=0的url返回時,循環早已結束,此時的x已經為2,因此實際上雖然httpbin.org返回的json告訴我們,get參數里的x為0,但閉包內訪問到的x已經是2了
解決方法我想了兩個,一個是利用回調函數構造時的變量空間,在構造函數時即產生這個參數,形如:
client = AsyncHTTPClient(self.io_loop) for x in xrange(3): def callback(respon,num=x): print x, num print respon.body if num == 2: self.stop() client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))
一種是再包一層閉包(這層閉包也可以放在for外面):
client = AsyncHTTPClient(self.io_loop) for x in xrange(3): def wrap(number): num = number def callback(respon): print x, num print respon.body if num == 2: self.stop() return callback client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x)) #wrap放在for外面: client = AsyncHTTPClient(self.io_loop) def wrap(number): num = number def callback(respon): print x, num print respon.body if num == 2: self.stop() return callback for x in xrange(3): client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))
思索了一下,閉包的內存占用問題應當是不可避免的?當循環體的每一項(x)是一個大內存對象時,內存占用等同于不用迭代器用列表進行循環,除了這兩種不知道還有沒有更優雅的解決方案。。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37331.html
摘要:瀏覽器的事件循環,前端再熟悉不過了,每天都會接觸的東西。可以看到,所謂的并不是瀏覽器定義了哪些任務是,瀏覽器各個線程只是忠實地循環自己的任務隊列,不停地執行其中的任務而已。 瀏覽器的事件循環,前端再熟悉不過了,每天都會接觸的東西。但我以前一直都是死記硬背:事件任務隊列分為macrotask和microtask,瀏覽器先從macrotask取出一個任務執行,再執行microtask內的所...
摘要:線程機制與事件機制一進程與線程進程程序的一次執行,它占有一片獨有的內存空間。事件響應模塊負責事件的管理。當事件發生時管理模塊會將回調函數及其數據添加到回調列隊中。但是子線程完全受主線程控制,且不得操作。向另一個線程發送消息。 JavaScript線程機制與事件機制 一、進程與線程 進程(process) 程序的一次執行,它占有一片獨有的內存空間。 可以通過windows任務管理器查...
摘要:事件完成,回調函數進入。我們來分析一段較復雜的代碼,看看你是否真的掌握了的執行機制第一輪事件循環流程分析如下整體作為第一個宏任務進入主線程,遇到,輸出。宏任務微任務第三輪事件循環宏任務執行結束,執行兩個微任務和。 關于JavaScript 首先js是單線程的,執行任務肯定是一個接著一個。在最新的html5中提出了web-worker,但是JavaScript是單線程這一核心沒有改變,一...
摘要:瀏覽器中與中事件循環與執行機制不同,不可混為一談。瀏覽器環境執行為單線程不考慮,所有代碼皆在執行線程調用棧完成執行。參考文章強烈推薦不要混淆和瀏覽器中的強烈推薦中的模塊強烈推薦理解事件循環一淺析定時器詳解 注意 在 node 11 版本中,node 下 Event Loop 已經與瀏覽器趨于相同。在 node 11 版本中,node 下 Event Loop 已經與瀏覽器趨于相同。在 ...
摘要:關于這部分有嚴格的文字定義,但本文的目的是用最小的學習成本徹底弄懂執行機制,所以同步和異步任務分別進入不同的執行場所,同步的進入主線程,異步的進入并注冊函數。宏任務微任務第三輪事件循環宏任務執行結束,執行兩個微任務和。 不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發工作,我們經常會遇到這樣的情況:給定的幾行代碼,我們需要知道其輸出內容和順序。 因為javascr...
閱讀 1310·2021-11-16 11:45
閱讀 2233·2021-11-02 14:40
閱讀 3872·2021-09-24 10:25
閱讀 3029·2019-08-30 12:45
閱讀 1255·2019-08-29 18:39
閱讀 2468·2019-08-29 12:32
閱讀 1588·2019-08-26 10:45
閱讀 1917·2019-08-23 17:01