使用chunkById方法时请不要进行排序!

2022-05-15 0 1,053

下面由Laravel教程栏目给大家介绍使用chunkById方法时请不要进行排序!,希望对需要的朋友有所帮助!

使用chunkById方法时请不要进行排序!

使用 chunkById 方法的时候请不要进行排序

最近在做开发任务的时候碰到了个诡异的问题,于是分享给大家

问题说明

由于需要批量处理数据,并且这个数据的量很大,一次全部取出然后执行是不现实的,幸运的是 Laravel 为我们提供了 chunkById 方法来让我们方便的处理。伪代码如下

Student::query()    ->where('is_delete', false)    ->orderBy('id', 'DESC')    ->chunkById(200, function($students) {            // 在这里进行逻辑处理    });

咋一眼看上去,并没有什么问题,但是实际执行代码的时候会发现 chunkById 只会执行第一次,第二次以后由于某种原因会停止执行。

查找原因

Laravel 的源码中 chunkById 代码如下

  public function chunkById($count, callable $callback, $column = null, $alias = null)    {        $column = is_null($column) ? $this->getModel()->getKeyName() : $column;        $alias = is_null($alias) ? $column : $alias;        $lastId = null;        do {            $clone = clone $this;            $results = $clone->forPageAfterId($count, $lastId, $column)->get();            $countResults = $results->count();            if ($countResults == 0) {                break;            }            if ($callback($results) === false) {                return false;            }            $lastId = $results->last()->{$alias};            unset($results);        } while ($countResults == $count);        return true;    }

看起来没什么问题,由于 while 循环是根据 $countResults == $count 来判断的,那么我们 dump 一下这两个变量就会发现, 第一次这两个是一致的,第二次由于数据不一致导致程序停止。

在上面的代码中, $count 是由 $results = $clone->forPageAfterId($count, $lastId, $column)->get(); 来获得的,

继续查看 forPageAfterId 方法

public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id'){    $this->orders = $this->removeExistingOrdersFor($column);    if (! is_null($lastId)) {        $this->where($column, '>', $lastId);    }    return $this->orderBy($column, 'asc')                ->take($perPage);}

我们可以看到,在这里返回的结果是 orderBy 进行升序排列的, 而我们的原始代码是进行降序排列,就会导致 count 不一致,从而使 chunkById 结束执行。

解决方案

把之前的 orderBy('id', 'desc') 移除即可。

Student::query()    ->where('is_delete', false)    ->chunkById(200, function($students) {            // 在这里进行逻辑处理    });

总结

以后使用 chunkById 或者 chunk 方法的时候不要添加自定义的排序

骚到老,学到老。。。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

【声明:根据2013年1月30日《计算机软件保护条例》2次修订第17条规定: 为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存 储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬! 鉴于此,也希望大家按此说明研究软件!】
本站所有源码尽量保证原汁原味,如有特殊情况会作出声明及标注,网站资源不做任何二次加密(原版加密除外,不影响程序使用的不会做解密处理),方便您更好的学习参考。 在您的能力范围内,为了大环境的良性发展,请尽可能的选择正版资源。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

即刻码站__国内靠谱的站长资源下载平台 php教程 使用chunkById方法时请不要进行排序! https://www.jike1995.com/36934.html

常见问题
  • 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务