【问题标题】:How to handle properly an ajax request如何正确处理ajax请求
【发布时间】:2014-07-19 05:14:48
【问题描述】:

我很好奇如何在我使用 Laravel 4 开发的测试应用程序中实现自动完成功能,只是为了练习。于是我google了一下,发现this library,唯一的依赖就是jQuery。

我不是 JavaScript 和 jQuery 方面的专家,我对 AJAX 也一无所知,我只是按照手册中的说明进行操作,并根据一些常识了解了它的整体工作原理。

这是应用自动完成操作的 JavaScript 代码:

$('#autocomplete').autocomplete({
    serviceUrl: '/search',
    onSelect: function(suggestion) {
        $('#autocomplete-suggestions').html("<a href='users/" + suggestion.data + "'>" + suggestion.value + "</a>");
    }
})

我在routes.php 文件中定义了服务,因为它很短:

Route::get('search', function() {
    $users = User::all();
    $response = array(
        "suggestions" => array()
    );
    foreach ($users as $user) {
        array_push($response["suggestions"], array("value" => $user->username, "data" => $user->id));
    }

    return Response::json($response);
});

这种工作方式让我感到好奇。我的意思是,每次用户在输入框中键入一个字符时,都会发出请求并执行服务,这是在 routes 方法中。这意味着从数据库中检索所有用户,将它们存储在一个数组中,然后将其全部复制到一个新数组中,以便根据预期输入进行调整。然后,在该 json 上进行实际搜索。

这对我来说似乎非常低效,因为此操作需要成本并且执行频率很高。如果搜索是针对数据库的查询,而不是对(可能)大量数据的几个副本的对象产品,那会更好。

另外,我用这段代码培养了一些新用户:

for ($i = 0; $i<1000; $i++) {
    $user = new User;
    $user->username = 'username' . $i;
    // assign the rest of the attributes
    $user->save();
}

而且搜索似乎没有正确进行。我想这是一个不同的问题,关于自动完成库本身。

所以,由于我对 AJAX 不熟悉,我只想知道这是否是通常的操作方式,或者这是否真的像我认为的那样是一个糟糕的想法。正确的做法是什么?

【问题讨论】:

  • 我认为你是对的。您的搜索路由处理程序应根据建议过滤用户并仅返回建议的用户。您现在构建它的方式效率低下,如果它真的过滤,我会感到惊讶。通常,每次更改都会发出新请求
  • @GolezTrol 所说的内容,以及您可以(并且可以说应该)缓存结果的附加评论。这将“减轻服务器的负载”,因为它可以检查缓存中的搜索结果,而不是一遍又一遍地访问数据库。

标签: php jquery ajax laravel autocomplete


【解决方案1】:

我是否应该在每个请求中返回所有用户并在客户端进行搜索?

绝对不是。当通过 AJAX 向您的服务器发出请求时,搜索查询将作为查询字符串参数提供。从他们的文档中:

为 Ajax 自动完成提供数据的网页,在我们的例子中 autocomplete.ashx 将收到带有查询字符串 ?query=Li 的 GET 请求, 并且必须返回以下格式的 JSON 数据

你可以从 Laravel 获得:$query = \Input::get('query');

您应该使用该字符串在您的 users 表上使用 eloquent 或其他方式进行搜索,并且只返回匹配的建议。

每次击键都发出 HTTP 请求很糟糕吗?

该库有一个名为deferRequestBy 的选项。当给定一个整数值(毫秒)时,它将等待这么长时间,直到在 keyUp 事件上执行请求。如果另一个 keyUp 事件进来,它将取消第一个。这有助于减少您可能正在运行的并发请求数。

https://github.com/devbridge/jQuery-Autocomplete/blob/master/src/jquery.autocomplete.js#L384-L384

直接来自他们的Readme on Github

deferRequestBy: 延迟 ajax 请求的毫秒数。默认值:0。

所以回答你的问题:

所以,由于我不熟悉 AJAX,我只想知道这是否是 通常的操作方式,或者如果这确实是一个糟糕的想法,就像我一样 思考。正确的做法是什么?

是的,如果您使用默认值 0,这可能是一个糟糕的主意。但不一定是这样。

您问题的其他要点:

  1. 您真的需要每次都去数据库并获取所有用户吗?缓存怎么样?

【讨论】:

  • 不错的评论,但它并没有真正回答问题。
  • 关于使用缓存的要点。简单地将$users = DB::table('users')-&gt;remember(10)-&gt;get(); 与 deferRequestBy 一起使用将是一个很好的解决方案。只需要在集合中搜索正确的用户并返回。
  • @GolezTrol 他/她提出了很多点,我已经尝试全部回答。
  • 我很欣赏这个答案,它确实让事情变得更加清晰。一方面,您建议在我的用户表上运行库使用的查询,另一方面,建议您和 cmets 缓存。将这两者合并在一起是解决方案吗?我从未见过 laravel 中的缓存,但不会每次在服务方法中调用 remember 会导致每次请求一次又一次地缓存,或者该方法是“智能”并正确管理它?
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 2018-04-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
相关资源
最近更新 更多