如何只考虑异步函数的最新调用(JS fetch/无限滚动)

How to only consider the lastest call of an asynchronous function (JS fetch / infinite scroll)

我不确定它是否称为无限滚动,但基本上,我有一个 table 有几千行,我在 ASP.Net 核心网站上显示。 table 有一个高级布局,其中样式在很大程度上取决于单元格内容。我通过控制器和 post 一个 JSON 文件填充内容和行的样式。

由于 JS 提取 api,我能够显示 table 的 20 行。 我可以顺利滚动到相邻的行

我还添加了一个单独的滚动条,所以我可以从第一行跳到最后一行。

问题是当我停止移动滚动条时,行仍然会更新几秒钟(有一些中间行,但幸运的是不是全部)直到达到目标行。似乎有一些延迟,就像我有几个异步调用等待处理一个接一个执行的更新函数。

有没有办法只考虑最近调用更新函数?

        $('#fields-scroll').on('input change', async function () {
            
            var row = $('#fields-scroll').val();
            
            await scroll(row);
        });

        async function scroll(row) {

            // Posts the metrics to the controller.
            const response = await fetch(`${window.location.href}Fields/Interact/`, {
                method: 'POST',
                body: JSON.stringify({ Row: row}),
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                }
            });

            // Gets the results from the controller.
            const results = await response.json();
            
            // Makes sure that there are actual results.
            if (results == null) {
                
                return;
            }

            var fields = results.fields;

            await populate(fields);
        }

感谢您的帮助!

我认为最简单的方法(不使用像 redux-saga 这样的外部库)是使用一个简单的去抖动器去抖动滚动动作:

const handler = _.debounce(async function () {
  console.log('SCROLLING');
  try {
    const row = $('#fields-scroll').val();
    await scroll(row);
  } catch (e) {
    console.log(e);
  }
}, 200);

$('#fields-scroll').on('input change', handler);

async function scroll(row) {
  // Posts the metrics to the controller.
  const response = await fetch(`${window.location.href}Fields/Interact/`, {
    method: 'POST',
    body: JSON.stringify({ Row: row }),
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
    },
  });
  // Gets the results from the controller.
  const results = await response.json();
  // Makes sure that there are actual results.
  if (results == null) {
    return;
  }

  var fields = results.fields;

  await populate(fields);
}
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="range" id="fields-scroll" />

如果这是您想要的效果,您可以根据自己的喜好调整去抖时间。在任何情况下,请记住始终将语句包装在 try-catch 块内的异步函数中,否则您将不会捕获抛出的错误。

太棒了,看起来效果很好!

我可能需要稍微调整一下时间以获得一些中间更新(并了解引擎盖下的内容:-)),但至少当我停止移动时它不会持续更新几秒钟滚动条。

PS 我刚刚将 const 更改为 var,因为当我刷新页面时它崩溃了(更准确地说,当我回到字段页面时)。