Использование thunks: Почему мой код не печатается последовательно?

Я пытаюсь понять thunks. Я прохожу курс Кайла Симпсона Rethinking Async JS по Линде.

У меня есть этот код:

function makeThunk(fn) {
    var args = [].slice.call(arguments, 1);
    return function(cb) {
        args.push(cb);
        fn.apply(null, args);
    }
}

function addAsync(x,y, cb) {
    setTimeout(function() {
        cb(x+y);
    }, 1000);
}


var thunk = makeThunk(addAsync, 10,15);

Теперь, когда я выполняю следующее:

thunk(function(sum) {
    console.log(sum * sum);
})

thunk(function(sum) {
    console.log(sum);
})

Результат - 625, напечатанных дважды.

Тем не менее, когда я выполняю

thunk(function(sum) {
    console.log(sum);
})
thunk(function(sum) {
    console.log(sum * sum);
})

Результат 25 выполнен дважды.

Я ожидаю, что в первом случае напечатано 625, а затем 25. И во втором случае напечатано 2525, а затем 625.

Почему мои ожидания неверны?

1 ответ

Решение
var thunk = makeThunk(addAsync, 10,15);

После этого закрытый массив args выглядит так:

[10, 15]

Теперь, если вы позвоните Thunk:

thunk(function one(sum) {
console.log(sum * sum);
})

Внутренние аргументы это:

[10, 15, one]

И функция выполняется в первый раз. Тогда вы звоните:

thunk(function two(sum) {
  console.log(sum);
})

Итак, args будет выглядеть так:

[10, 15, one, two]

Так addAsync называется как:

addAsync(10, 15, one, two)

Таким образом, cb снова равен единице, поэтому первая функция выполняется дважды.


Чтобы решить эту проблему, вы можете изменить модификацию с помощью push в неизменяемый concat:

return function(cb) {
    fn.apply(null, args.concat(cb));
}
Другие вопросы по тегам