Значение Lazy Evaluation в Javascript

в Boilerplate, который я использую для проекта React Redux, я встретил этот комментарий в коде:

Это thunk, то есть это функция, которая немедленно возвращает функция для ленивой оценки. Это невероятно полезно для создания асинхронные действия, особенно в сочетании с сокращением!

Теперь, если я это правильно понимаю, ленивая оценка - это процесс возврата функции. Какова цель возврата функции, и как это отлично подходит для создания асинхронных действий?

О, также, это тонкая функция?

Ответ 1

Thunk - это функция, которая не принимает никаких аргументов и возвращает что-то (или делает что-то как побочный эффект). Ленивая оценка - это процесс отсрочки оценки выражения до конца, и это можно сделать с помощью thunks:

// 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. Вы можете лениво производить действие (или действия) либо синхронно, либо асинхронно. В большинстве случаев вы хотели бы использовать это, чтобы вы могли отправлять асинхронно.

См. также:

Ответ 2

Обычно создатели действия Redux являются синхронными, что означает, что при их вызове вы ожидаете, что они вернут действие и редукторы, которые будут вызваны немедленно, и состояние будет изменено "на лету". Вы также ожидаете, что этот процесс будет очень быстрым, потому что будет выполняться только небольшая операция с привязкой к процессору.

Однако иногда вы хотите, чтобы ваш создатель действия перешел на сервер или выполнял некоторые операции, не связанные с процессором, которые потребовались бы некоторое время. Это, когда имеет смысл возвращать функцию вместо этого.

Когда ваш создатель действия возвращает функцию, он немедленно возвращается. С точки зрения того, кто называет создателя действия, ничего странного не произошло. Все как обычно. Но внутренне вместо того, чтобы возвращать объект Action, ваш создатель действия возвратил такую ​​функцию.

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

Обычно DoSomethingAsync возвращает Object. Что делает промежуточное ПО Redux-Thunk, это , чтобы обнаружить, что функция была возвращена вместо этого. Таким образом, он не делает ничего, кроме как вызвать эту функцию, передавая тот же самый dispatch, как обычно.

Теперь ответная реакция обратного вызова на вызов dispatch для отправки действия SYNC.