首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >grequests在哪方面是异步的?

grequests在哪方面是异步的?
EN

Stack Overflow用户
提问于 2013-04-15 20:57:58
回答 3查看 39.7K关注 0票数 43

我使用python请求库已经有一段时间了,最近需要异步发出一个请求,这意味着我想发送HTTP请求,让我的主线程继续执行,并在请求返回时调用一个回调。

当然,我被引导到grequest库(https://github.com/kennethreitz/grequests),但我对其行为感到困惑。例如:

代码语言:javascript
复制
import grequests

def print_res(res):
    from pprint import pprint
    pprint (vars(res))

req = grequests.get('http://www.codehenge.net/blog', hooks=dict(response=print_res))
res = grequests.map([req])

for i in range(10):
    print i

上面的代码将产生以下输出:

代码语言:javascript
复制
<...large HTTP response output...>

0
1
2
3
4
5
6
7
8
9

grequests.map()调用显然会阻塞,直到HTTP响应可用为止。似乎我误解了这里的“异步”行为,而grequest库只是用于并发执行多个HTTP请求,并将所有响应发送到单个回调。这是准确的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-15 21:38:06

.map()意味着并行运行多个URL的检索,并且实际上会等待这些任务完成(调用gevent.joinall(jobs))。

使用Pool instance,改用.send()派生作业

代码语言:javascript
复制
req = grequests.get('http://www.codehenge.net/blog', hooks=dict(response=print_res))
job = grequests.send(req, grequests.Pool(1))

for i in range(10):
    print i

如果没有池,.send()调用仍然会阻塞,但只会阻塞它执行的gevent.spawn()调用。

票数 57
EN

Stack Overflow用户

发布于 2017-07-05 12:26:41

如果您不想使用grequests,那么可以使用requests +标准库中的threading模块来实现带有回调的请求。这实际上非常简单,如果你想做的只是发送带有回调的请求,那么这个接口比grequests提供的接口更好。

代码语言:javascript
复制
from threading import Thread

from requests import get, post, put, patch, delete, options, head



request_methods = {
    'get': get,
    'post': post,
    'put': put,
    'patch': patch,
    'delete': delete,
    'options': options,
    'head': head,
}


def async_request(method, *args, callback=None, timeout=15, **kwargs):
    """Makes request on a different thread, and optionally passes response to a
    `callback` function when request returns.
    """
    method = request_methods[method.lower()]
    if callback:
        def callback_with_args(response, *args, **kwargs):
            callback(response)
        kwargs['hooks'] = {'response': callback_with_args}
    kwargs['timeout'] = timeout
    thread = Thread(target=method, args=args, kwargs=kwargs)
    thread.start()

您可以验证它的工作方式是否类似于JS中的AJAX调用:在另一个线程上发送请求,在主线程上执行一些操作,当请求返回时调用回调。这个回调只是打印出响应内容。

代码语言:javascript
复制
async_request('get', 'http://httpbin.org/anything', callback=lambda r: print(r.json()))
for i in range(10):
    print(i)
票数 11
EN

Stack Overflow用户

发布于 2017-02-15 14:32:19

创建一个请求列表,然后用.imap发送它们

代码语言:javascript
复制
event_list = [grequests.get(url_viol_card, params={"viol": i},
              session=session) for i in print_ev_list]
for r in grequests.imap(event_list, size=5):
    print(r.request.url)

  • session is requests.Session() object (optional)
  • size=5 send 5 requests :只要其中一个请求完成,下一个请求就会被发送
  • 在本例中,当任何请求(无序的)完成时,它的url都会被打印出来
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16015749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档