【问题标题】:What is the meaning of lazy evaluation in this comment?这条评论中懒惰的评估是什么意思?
【发布时间】:2016-12-18 16:40:19
【问题描述】:

在我用于 React Redux 项目的样板文件中,我在代码中遇到了以下注释:

这是一个 thunk,意味着它是一个立即返回一个 惰性求值函数。它对于创建非常有用 异步操作,尤其是与 redux-thunk 结合使用时!

现在,如果我理解正确的话,惰性求值就是返回函数的过程。但是,返回函数的目的是什么?这对于创建异步操作有什么好处?

哦也,thunk 只是一个函数吗?

【问题讨论】:

    标签: javascript redux lazy-evaluation redux-thunk


    【解决方案1】:

    通常,Redux 动作创建者是同步的,这意味着,当您调用它们时,您会期望它们返回一个 Action,并且 Reducer 会立即被调用,并且状态会即时更改。您还希望这个过程非常快,因为只会执行一个小型 CPU 密集型操作。

    但是,有时您希望动作创建者转到服务器,或者执行一些需要一段时间的非 CPU 绑定操作。这时候返回一个函数才是有意义的。

    当您的动作创建者返回一个函数时,它会立即返回。从谁调用动作创建者的角度来看,并没有发生什么奇怪的事情。一切如常。但是在内部,您的操作创建者没有返回 Action 对象,而是返回了这样的函数..

    function DoSomethingAsync() {
        return (dispatch) => {
            // go do something realllly slowly.
            // ok now get the RESULT and call a regular action
            dispatch(mySyncAction(RESULT));
        }
    }
    

    通常DoSomethingAsync 会返回一个ObjectRedux-Thunk 中间件的作用是检测返回了一个函数。因此,它只调用这个函数并像往常一样传递相同的dispatch

    现在是回调函数调用dispatch 来调度SYNC 操作。

    【讨论】:

      【解决方案2】:

      thunk 是一个不带参数并返回某些内容(或作为副作用执行某些操作)的函数。惰性求值是将表达式的求值推迟到以后的过程,这可以通过 thunk 来完成:

      // Not lazy
      var value = 1 + 1  // immediately evaluates to 2
      
      // Lazy
      var lazyValue = () => 1 + 1  // Evaluates to 2 when lazyValue is *invoked*
      

      你也可以让返回值变得懒惰:

      // Not lazy
      var add = (x, y) => x + y
      var result = add(1, 2)  // Immediately evaluates to 3
      
      // Lazy
      var addLazy = (x, y) => () => x + y;
      var result = addLazy(1, 2)  // Returns a thunk which *when evaluated* results in 3.
      

      最后我们可以推迟一些异步操作:

      // Not lazy
      var callApi = spec => fetch(spec.url, spec.options);
      // Immediately returns a Promise which will be fulfilled when the network response is processed.
      var result = callApi({url: '/api', options: {}});
      
      // Lazy
      var callApiLazy = spec => () => fetch(spec.url, spec.options);
      var result = callApiLazy({url: '/api', options: {}});
      // result is a thunk that when evaluated will return a Promise ...
      // which will be fulfilled when the network response is processed.
      

      现在 thunk 没有接受零参数 - 您可以返回一个需要更多参数才能成功评估的惰性值。这被称为“currying”:

      // Curried add (not lazy)
      var add = x => y => x + y
      var add3 = add(3)
      var result = add3(7)  // Immediately evaluates to 10
      

      redux-thunk 允许您将函数而不是对象作为操作返回,并使用 dispatch 函数调用您的函数。然后,您可以同步或异步地懒惰地产生一个(或多个)动作。大多数时候,您会希望使用它来允许您异步调度。

      另见:

      【讨论】:

      • "takes no arguments" 在这种情况下不正确... redux thunk 接受 dispatch,这允许延迟操作调度。
      • 是的,redux-thunk 将 thunk 一词延伸了一点。我会把它添加进去。
      • 你好,这很有趣!所以基本上在第一个例子中,value 不是懒惰的,因为它是一个变量,它会立即被评估。其中lazyValue 是变量的函数,因此在调用变量之前不会进行评估。在第二个示例中,not lazy 是否会因为 result 正在调用 adds 函数而被考虑?另外,对于示例 2 中的 lazy,这是 result 上的拼写错误吗?不应该是addLazy(1,2)吗?
      • 是的,这是一个错字@MichaelJones - 谢谢!至于其余部分,lazyValue 是一个变量,其中包含一个函数,调用该函数时会产生我们想要的值,value 包含我们想要的值。
      • 好的,所以在lazynot lazy 的第二组中是我感到困惑的地方。对于not lazyadd 持有一个函数,这不会使它成为lazy,因为直到result 调用add(1,2) 才会对其进行评估。至于示例的lazy 部分,addLazy 有一个返回函数的函数是否正确?所以基本上,这是否意味着result 甚至不评估addLazyaddLazy 仅在调用 result 变量时才被评估,对吗?我想我已经开始掌握这个窍门了,我希望无论如何!
      猜你喜欢
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 2015-02-09
      • 2011-03-29
      相关资源
      最近更新 更多