摘要:問題出現(xiàn)在循環(huán)體內(nèi)的回調(diào)函數(shù),用一個很簡單的例子舉例此例子忽略了等待回調(diào)函數(shù)完成的實現(xiàn)不實現(xiàn)這個會導(dǎo)致作為單個文件運行的時候,還沒獲得結(jié)果就退出了,在中的提供了相關(guān)功能這個地址的作用是返回了請求的對象,形如但實際上,由于回調(diào)函
問題出現(xiàn)在循環(huán)體內(nèi)的回調(diào)函數(shù),用一個很簡單的例子舉例:
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)
此例子忽略了等待回調(diào)函數(shù)完成的wait實現(xiàn)(不實現(xiàn)這個會導(dǎo)致作為單個文件運行的時候,還沒獲得結(jié)果就退出了),在tornado.testing中的AsyncTestCase提供了相關(guān)功能
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" }
但實際上,由于回調(diào)函數(shù)特殊的特性:訪問閉包內(nèi)局部變量的當(dāng)前值。易知,在第一個請求
http://httpbin.org/get?x=0的url返回時,循環(huán)早已結(jié)束,此時的x已經(jīng)為2,因此實際上雖然httpbin.org返回的json告訴我們,get參數(shù)里的x為0,但閉包內(nèi)訪問到的x已經(jīng)是2了
解決方法我想了兩個,一個是利用回調(diào)函數(shù)構(gòu)造時的變量空間,在構(gòu)造函數(shù)時即產(chǎn)生這個參數(shù),形如:
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))
思索了一下,閉包的內(nèi)存占用問題應(yīng)當(dāng)是不可避免的?當(dāng)循環(huán)體的每一項(x)是一個大內(nèi)存對象時,內(nèi)存占用等同于不用迭代器用列表進行循環(huán),除了這兩種不知道還有沒有更優(yōu)雅的解決方案。。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37331.html
摘要:瀏覽器的事件循環(huán),前端再熟悉不過了,每天都會接觸的東西??梢钥吹?,所謂的并不是瀏覽器定義了哪些任務(wù)是,瀏覽器各個線程只是忠實地循環(huán)自己的任務(wù)隊列,不停地執(zhí)行其中的任務(wù)而已。 瀏覽器的事件循環(huán),前端再熟悉不過了,每天都會接觸的東西。但我以前一直都是死記硬背:事件任務(wù)隊列分為macrotask和microtask,瀏覽器先從macrotask取出一個任務(wù)執(zhí)行,再執(zhí)行microtask內(nèi)的所...
摘要:線程機制與事件機制一進程與線程進程程序的一次執(zhí)行,它占有一片獨有的內(nèi)存空間。事件響應(yīng)模塊負責(zé)事件的管理。當(dāng)事件發(fā)生時管理模塊會將回調(diào)函數(shù)及其數(shù)據(jù)添加到回調(diào)列隊中。但是子線程完全受主線程控制,且不得操作。向另一個線程發(fā)送消息。 JavaScript線程機制與事件機制 一、進程與線程 進程(process) 程序的一次執(zhí)行,它占有一片獨有的內(nèi)存空間。 可以通過windows任務(wù)管理器查...
摘要:事件完成,回調(diào)函數(shù)進入。我們來分析一段較復(fù)雜的代碼,看看你是否真的掌握了的執(zhí)行機制第一輪事件循環(huán)流程分析如下整體作為第一個宏任務(wù)進入主線程,遇到,輸出。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。 關(guān)于JavaScript 首先js是單線程的,執(zhí)行任務(wù)肯定是一個接著一個。在最新的html5中提出了web-worker,但是JavaScript是單線程這一核心沒有改變,一...
摘要:瀏覽器中與中事件循環(huán)與執(zhí)行機制不同,不可混為一談。瀏覽器環(huán)境執(zhí)行為單線程不考慮,所有代碼皆在執(zhí)行線程調(diào)用棧完成執(zhí)行。參考文章強烈推薦不要混淆和瀏覽器中的強烈推薦中的模塊強烈推薦理解事件循環(huán)一淺析定時器詳解 注意 在 node 11 版本中,node 下 Event Loop 已經(jīng)與瀏覽器趨于相同。在 node 11 版本中,node 下 Event Loop 已經(jīng)與瀏覽器趨于相同。在 ...
摘要:關(guān)于這部分有嚴(yán)格的文字定義,但本文的目的是用最小的學(xué)習(xí)成本徹底弄懂執(zhí)行機制,所以同步和異步任務(wù)分別進入不同的執(zhí)行場所,同步的進入主線程,異步的進入并注冊函數(shù)。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。 不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作,我們經(jīng)常會遇到這樣的情況:給定的幾行代碼,我們需要知道其輸出內(nèi)容和順序。 因為javascr...
閱讀 1325·2021-11-16 11:45
閱讀 2250·2021-11-02 14:40
閱讀 3888·2021-09-24 10:25
閱讀 3037·2019-08-30 12:45
閱讀 1269·2019-08-29 18:39
閱讀 2481·2019-08-29 12:32
閱讀 1620·2019-08-26 10:45
閱讀 1927·2019-08-23 17:01