首页 > 解决方案 > 如何在对谷歌搜索的 API 调用之间引入延迟以避免 OVER_QUERY_LIMIT 错误

问题描述

我正在使用PlacesSearchBar提供一个自动完成选项来在我的 Xamarin Forms 应用程序中查找地点。

从组件的角度来看,这工作正常,但谷歌 APIOVER_QUERY_LIMIT在一两次尝试后返回我。

我想我知道问题出在哪里,这个组件每秒不止一次调用这个 google API,这使我成为 google 逻辑的可疑模式,它开始向我返回OVER_QUERY_LIMIT状态。但是我看不到如何在这些调用之间引入延迟。

这是我使用这个组件的方式。

<searchplaces:PlacesBar x:Name="edtSearch" MinimumSearchText="6"  ApiKey="<API KEY>" Placeholder="Please enter your destination address"></searchplaces:PlacesBar>
<AbsoluteLayout>
    <ActivityIndicator x:Name="spinner" IsRunning="false" AbsoluteLayout.LayoutBounds="0.5, 0.1, 50, 50" AbsoluteLayout.LayoutFlags="PositionProportional" />
    <ListView x:Name="lvPlaces" ItemsSource="{Binding .}"  RowHeight="60"
          VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
          IsVisible="False" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="SizeProportional">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout BackgroundColor="#2B2C30" Orientation="Vertical" Margin="0,0,0,2" Padding="5,5,5,5" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" >
                        <Label Text="{Binding Description}" TextColor="#EAEDF7" FontSize="Medium" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</AbsoluteLayout>

在我的.cs构造函数上,我有这个:

edtSearch.TextChanged += async (sender, e) => 
            {
                if (!string.IsNullOrEmpty(e.NewTextValue) && (e.NewTextValue.Length >= edtSearch.MinimumSearchText))
                {
                    lvPlaces.IsVisible = false;
                    spinner.IsVisible = true;
                    spinner.IsRunning = true;

                    edtSearch.IsReadOnly = true; // try 1: to introduce delay
                    await Task.Delay(800);  
                }
                else
                {
                    lvPlaces.IsVisible = true;
                    spinner.IsRunning = false;
                    spinner.IsVisible = false;
                    edtSearch.IsReadOnly = false;
                }
            };
            edtSearch.PlacesRetrieved = async (sender, result) =>
            {
                this.BindingContext = result.AutoCompletePlaces;
                spinner.IsRunning = false;
                spinner.IsVisible = false;
                edtSearch.IsReadOnly = false;

                if (result.AutoCompletePlaces != null && result.AutoCompletePlaces.Count > 0)
                    lvPlaces.IsVisible = true;

                if (result.Status == "OVER_QUERY_LIMIT")
                {
                    await Task.Delay(2000); // try 2: to introduce delay
                }
                };
            edtSearch.MinimumSearchText = 6; 

PlacesSearchBar 组件代码上,我看到了这个逻辑:

async void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.NewTextValue) && e.NewTextValue.Length >= MinimumSearchText)
            {
                var predictions = await Places.GetPlaces(e.NewTextValue, ApiKey, Bias, Components, Type, Language);
                if (PlacesRetrieved != null && predictions != null)
                    OnPlacesRetrieved(predictions);
                else
                    OnPlacesRetrieved(new AutoCompleteResult());
            }
            else
            {
                OnPlacesRetrieved(new AutoCompleteResult());
            }
        } 

因为这是一个事件,所以无论我从这个组件外部做什么,它都不会影响原始组件的这种行为。

OVER_QUERY_LIMIT有人可以帮我在使用这个时如何克服这个问题Auto complete text box

问候基兰

标签: google-mapsxamarin.forms.net-core

解决方案


我认为我们设法解决了这个问题,问题是我们没有将我们的项目连接到计费帐户,因此谷歌允许的每秒只有 1 个请求的最小请求。

一旦我们连接到一个计费帐户,这至少现在就开始工作了。


推荐阅读