src/Db/Orm/ActiveRelationTrait.php
protected function populateRelationAsyncMultiple($name, &$primaryModels, $viaModels = null, $viaQuery = null) {
        // https://github.com/yiisoft/yii2/issues/3197
        // delay indexing related models after buckets are built
        $indexBy = $this->indexBy;
        $this->indexBy = null;
        return $this->all()->otherwise(function() {
            return [];
        })->then(
            function($models) use (&$primaryModels, $name, $viaModels, $viaQuery, $indexBy) {
                if (isset($viaModels, $viaQuery)) {
                    $buckets = $this->buildBuckets($models, $this->link, $viaModels, $viaQuery->link);
                } else {
                    $buckets = $this->buildBuckets($models, $this->link);
                }
                $this->indexBy = $indexBy;
                if ($this->indexBy !== null && $this->multiple) {
                    $buckets = $this->indexBuckets($buckets, $this->indexBy);
                }

                $link = array_values(isset($viaQuery) ? $viaQuery->link : $this->link);
                foreach ($primaryModels as $i => $primaryModel) {
                    if ($this->multiple && count($link) === 1 && is_array($keys = $primaryModel[reset($link)])) {
                        $value = [];
                        foreach ($keys as $key) {
                            $key = $this->normalizeModelKey($key);
                            if (isset($buckets[$key])) {
                                if ($this->indexBy !== null) {
                                    // if indexBy is set, array_merge will cause renumbering of numeric array
                                    foreach ($buckets[$key] as $bucketKey => $bucketValue) {
                                        $value[$bucketKey] = $bucketValue;
                                    }
                                } else {
                                    $value = array_merge($value, $buckets[$key]);
                                }
                            }
                        }
                    } else {
                        $key = $this->getModelKey($primaryModel, $link);
                        $value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
                    }
                    if ($primaryModel instanceof ActiveRecordInterface) {
                        $primaryModel->populateRelation($name, $value);
                    } else {
                        $primaryModels[$i][$name] = $value;
                    }
                }
                if ($this->inverseOf !== null) {
                    $this->populateInverseRelation($primaryModels, $models, $name, $this->inverseOf);
                }

                return $models;
            }
        );
    }
protected function populateRelationAsyncMultiple($name, &$primaryModels, $viaModels = null, $viaQuery = null) {
        // https://github.com/yiisoft/yii2/issues/3197
        // delay indexing related models after buckets are built
        $indexBy = $this->indexBy;
        $this->indexBy = null;
        return $this->all()->otherwise(function() {
            return [];
        })->then(
            function($models) use (&$primaryModels, $name, $viaModels, $viaQuery, $indexBy) {
                if (isset($viaModels, $viaQuery)) {
                    $buckets = $this->buildBuckets($models, $this->link, $viaModels, $viaQuery->link);
                } else {
                    $buckets = $this->buildBuckets($models, $this->link);
                }
                $this->indexBy = $indexBy;
                if ($this->indexBy !== null && $this->multiple) {
                    $buckets = $this->indexBuckets($buckets, $this->indexBy);
                }

                $link = array_values(isset($viaQuery) ? $viaQuery->link : $this->link);
                foreach ($primaryModels as $i => $primaryModel) {
                    if ($this->multiple && count($link) === 1 && is_array($keys = $primaryModel[reset($link)])) {
                        $value = [];
                        foreach ($keys as $key) {
                            $key = $this->normalizeModelKey($key);
                            if (isset($buckets[$key])) {
                                if ($this->indexBy !== null) {
                                    // if indexBy is set, array_merge will cause renumbering of numeric array
                                    foreach ($buckets[$key] as $bucketKey => $bucketValue) {
                                        $value[$bucketKey] = $bucketValue;
                                    }
                                } else {
                                    $value = array_merge($value, $buckets[$key]);
                                }
                            }
                        }
                    } else {
                        $key = $this->getModelKey($primaryModel, $link);
                        $value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
                    }
                    if ($primaryModel instanceof ActiveRecordInterface) {
                        $primaryModel->populateRelation($name, $value);
                    } else {
                        $primaryModels[$i][$name] = $value;
                    }
                }
                if ($this->inverseOf !== null) {
                    $this->populateInverseRelation($primaryModels, $models, $name, $this->inverseOf);
                }

                return $models;
            }
        );
    }
Populate relation for multiple primary models
@param string                       $name
@param ActiveRecordInterface[]      $primaryModels
@param ActiveRecordInterface[]|null $viaModels
@param ActiveQuery|null             $viaQuery
@return ExtendedPromiseInterface with ActiveRecordInterface[]