Javascript中懒惰评估的意义

时间:2016-08-11 19:43:06

标签: javascript redux redux-thunk

在我用于React Redux项目的Boilerplate中的

我在代码中看到了这条评论:

  

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

现在,如果我理解正确,懒惰评估是返回函数的过程。返回函数的目的是什么,以及如何创建异步操作?

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

2 个答案:

答案 0 :(得分:23)

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函数调用函数。然后,您可以同步或异步地懒洋洋地生成一个或多个动作。大多数情况下,您可能希望使用它来允许您异步分派。

另见:

答案 1 :(得分:1)

通常情况下,Redux动作创建者是同步的,这意味着,当你调用它们时,你会期望它们返回一个动作,并立即调用Reducers并动态改变状态。您还希望此过程非常快,因为只执行一个小的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操作。