好程序员分享循环内的回调函数

简介:   好程序员分享循环内的回调函数,问题出现在循环体内的回调函数,用一个很简单的例子举例:  for x in xrange(3):1.  print "requests begin:%s"%x2.

  好程序员分享循环内的回调函数,问题出现在循环体内的回调函数,用一个很简单的例子举例:

  for x in xrange(3):
1.

  print "requests begin:%s"%x


2.

  def callback(respon):


3.

  print x


4.

  print respon.body


5.

  client.fetch("http://httpbin.org/get?x=%s" % x, callback)

  此例子忽略了等待回调函数完成的wait实现(不实现这个会导致作为单个文件运行的时候,还没获得结果就退出了),在tornado.testing中的AsyncTestCase提供了相关功能
  httpbin.org/get这个地址的作用是返回了请求的json对象,形如:
  {
1.

  "args": {


2.

  "x": "0"


3.

  },


4.

  "headers": {


5.

  "Accept-Encoding": "gzip",


6.

  "Connection": "close",


7.

  "Host": "httpbin.org",


8.

  "X-Request-Id": "95df3c15-7ed0-4a6d-830d-fb9629e66515"


9.

  },


10.

  "origin": "192.81.129.91",


11.

  "url": "http://httpbin.org/get?x=0"


12.

  }

  但实际上,由于回调函数特殊的特性:访问闭包内局部变量的当前值。易知,在第一个请求
  http://httpbin.org/get?x=0的url返回时,循环早已结束,此时的x已经为2,因此实际上虽然httpbin.org返回的json告诉我们,get参数里的x为0,但闭包内访问到的x已经是2了
  解决方法我想了两个,一个是利用回调函数构造时的变量空间,在构造函数时即产生这个参数,形如:
  client = AsyncHTTPClient(self.io_loop)
1.

  for x in xrange(3):


2.

  def callback(respon,num=x):


3.

  print x, num


4.

  print respon.body


5.

  if num == 2:


6.

  self.stop()


7.

  client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))

  一种是再包一层闭包(这层闭包也可以放在for外面):
  client = AsyncHTTPClient(self.io_loop)
1.

  for x in xrange(3):


2.

  def wrap(number):


3.

  num = number


4.

  def callback(respon):


5.

  print x, num


6.

  print respon.body


7.

  if num == 2:


8.

  self.stop()


9.

  return callback


10.

  client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))


11.

  #wrap放在for外面:


12.

  client = AsyncHTTPClient(self.io_loop)


13.

  def wrap(number):


14.

  num = number


15.

  def callback(respon):


16.

  print x, num


17.

  print respon.body


18.

  if num == 2:


19.

  self.stop()


20.

  return callback


21.

  for x in xrange(3):


22.

  client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))

  思索了一下,闭包的内存占用问题应当是不可避免的?当循环体的每一项(x)是一个大内存对象时,内存占用等同于不用迭代器用列表进行循环,除了这两种不知道还有没有更优雅的解决方案。。

相关文章
|
1月前
javascirpt中的for...in循环
javascirpt中的for...in循环
|
30天前
|
开发框架 JavaScript 前端开发
描述JavaScript事件循环机制,并举例说明在游戏循环更新中的应用。
JavaScript的事件循环机制是单线程处理异步操作的关键,由调用栈、事件队列和Web APIs构成。调用栈执行函数,遇到异步操作时交给Web APIs,完成后回调函数进入事件队列。当调用栈空时,事件循环取队列中的任务执行。在游戏开发中,事件循环驱动游戏循环更新,包括输入处理、逻辑更新和渲染。示例代码展示了如何模拟游戏循环,实际开发中常用框架提供更高级别的抽象。
14 1
C4.
|
1月前
|
程序员 C语言 开发者
C语言中如何改变循环执行的状态
C语言中如何改变循环执行的状态
C4.
15 0
|
1月前
|
C语言
20.C语言:用continue语句提前终止循环
20.C语言:用continue语句提前终止循环
14 0
|
6月前
|
Python
python之while循环,无限循环,while循环的嵌套的定义和使用。
python之while循环,无限循环,while循环的嵌套的定义和使用。
|
8月前
|
索引
在循环内使用闭包(Closures)
在循环内使用闭包(Closures)
59 0
|
存储 JavaScript
为什么我要说:柯里化 == 闭包+递归?
柯里化是 JS 高程中不可或缺的重心,本篇带你来冲一冲它!!
|
JavaScript 前端开发 Java
面试官:Lambda 表达式中的 forEach 如何提前终止?这次被问倒了!
面试官:Lambda 表达式中的 forEach 如何提前终止?这次被问倒了!
面试官:Lambda 表达式中的 forEach 如何提前终止?这次被问倒了!
JavaScirpt基础do while循环
JavaScirpt基础do while循环
62 0
JavaScirpt基础for循环
JavaScirpt基础for循环
65 0