当前位置: 首页 > 知识库问答 >
问题:

如何在React(Async/Await)中创建原子进程?

韩宏朗
2023-03-14

想象一下一个按下按钮就能被喜欢的帖子。这个按钮修改了一个远程数据库,所以需要一点时间来将like与特定的帖子相关联。

 state = {
    isLiked: false,
 }

 handlePress = () => {
    this.setState(
      {
        isLiked: !this.state.isLiked,
      },
      this.handleLike
    );
  };

  handleLike = async () => {
    const { postId } = this.props;

    try {
      console.log(isLiked ? "Liking" : "Disliking")
      await db.processLike(postId);
    } catch (err) {
      // If an error has occurred, reverse the 'isLiked' state
      this.setState({
        isLiked: !this.state.isLiked,
      });

      // TODO - Alert the error to the user in a toast
      console.log(err);
    }

    console.log("DONE");
  };

不喜欢

做了<-------不喜欢做

做完<--------喜欢做完

 state = {
    isLiking: false,
    isLiked: false,
 }

 handlePress = () => {

    if (this.state.isLiking) return; <------------------------------------

    this.setState(
      {
        isLiking: true, <------------------------------------
        isLiked: !this.state.isLiked,
      },
      this.handleLike
    );
  };

  handleLike = async () => {
    const { postId } = this.props;

    try {
      console.log(isLiked ? "Liking" : "Disliking"); 
      await db.processLike(postId);
    } catch (err) {
      // If an error has occurred, reverse the 'isLiked' state
      this.setState({
        isLiked: !this.state.isLiked,
      });

      // TODO - Alert the error to the user in a toast
      console.log(err);
    }

    this.setState({ isLiking: false }); <------------------------------------

    console.log("DONE");
  };
export const debounce = (func, wait, immediate) => {
  /*
    Returns a function, that, as long as it continues to be invoked, will not
    be triggered. The function will be called after it stops being called for
    N milliseconds. If `immediate` is passed, trigger the function on the
    leading edge, instead of the trailing.
  */

  let timeout;
  return function () {
    let context = this,
      args = arguments;

    let later = function () {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    let callNow = immediate && !timeout;

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };
};

...

debuncedHandlePress = debounce(this.handlePress, 500); // Now, when the button is pressed, it will call this function, instead of the original handlePress

共有1个答案

吴腾
2023-03-14

解决办法是立即禁用按钮。使用setstate,您不能期望立即更新islinking,这就是您恼火的原因。解决方案之一是使用标志变量而不是使用state

你可以用这种方法修好。

 state = {
    isLiked: false,
 }

 constructor(props) {
    this.isLiking = false; <------------------------------------
 }
 

 handlePress = () => {
    this.isLiking = true; <------------------------------------
    this.setState(
      {
        isLiked: !this.state.isLiked,
      },
      this.handleLike
    );
  };

  handleLike = async () => {
    const { postId } = this.props;

    try {
      console.log(isLiked ? "Liking" : "Disliking"); 
      await db.processLike(postId);
    } catch (err) {
      // If an error has occurred, reverse the 'isLiked' state
      this.setState({
        isLiked: !this.state.isLiked,
      });

      // TODO - Alert the error to the user in a toast
      console.log(err);
    }

    this.isLiking = false; <------------------------------------

    console.log("DONE");
  };
 类似资料:
  • 问题内容: 我开始使用React Native进行编程,并且习惯于使用以下语法: 但是我不知道如何在共享包中使其与React JS和React Native兼容。我如何才能做到这一点,以使其在两个平台上都能正常工作? 谢谢! 问题答案: React Native带有Babel和一些Babel预设,而Web上的React只是与React相关的代码。 如果您今天想在网络上使用async / await

  • Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。 Async function 让我们以 async 这个关键字开始。它可以被放置在一个函数前面,如下所示: async function f() { return 1; } 在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被

  • 在第一章节,我们简要介绍了async/.await,并用它来构建一个简单的服务器。本章将更为详细讨论async/.await的它如何工作以及如何async代码与传统的 Rust 程序不同。 async/.await是 Rust 语法的特殊部分,它使得可以 yield 对当前线程的控制而不是阻塞,从而允许在等待操作完成时,其他代码可以运行。 async有两种主要的使用方式:async fn和asyn

  • 用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。 为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。 请注意,async和await是针对coroutin

  • 我已经复习了/,在复习了几篇文章之后,我决定自己测试一下。然而,我似乎无法理解为什么这不起作用: 控制台输出以下内容(节点V8.6.0): >外:“对象承诺” >内部:嘿那里 为什么函数内部的日志消息会在之后执行?我认为创建/的原因是为了使用异步任务执行同步执行。 有没有一种方法可以使用函数内部返回的值,而不用后面的?

  • 最后,/很快将在除IE以外的所有主要浏览器中得到支持。因此,现在我们可以开始使用/编写更易读的代码,但是有一个问题。很多人像这样使用异步等待: