привязать аргументы к функции javascript

#javascript #ajax #bind

#javascript #ajax #привязка

Вопрос:

я пытаюсь запустить второй запрос, когда первый был разрешен следующим образом:

 const fn1 = secondQuery => $.get('1.json', data => secondQuery());
const fn2 = secondQuery => $.get('2.json', data => secondQuery());
const fn3 = secondQuery => $.get('3.json', data => secondQuery());
const fn4 = secondQuery => $.get('4.json', data => secondQuery());

const queries = [fn1, fn2, fn3, fn4];

const queriesWithArgs = queries.map((queryFn, index, arr) => {
    const nextQuery = arr[index   1];

    if (!nextQuery) {
        return
    }

    return queryFn.bind(queryFn, nextQuery);
});

queriesWithArgs[0]();
  

но все еще получаю ошибку TypeError: secondQuery не является функцией, в то время как запросы к 1.json и 2.json работают нормально, fn2, похоже, не получает fn3 в качестве аргумента.
Можете ли вы объяснить, как это работает?

Комментарии:

1. Чего queryFn.bind(queryFn, nextQuery); предполагается достичь?

2. Ах, я полагаю, вы имели в виду queryFn.bind(null, nextQuery); или просто () => queryfn(nextQuery) ?

3. ^^ null имело бы больше смысла в качестве первого аргумента bind там.

4. да, @Bergi, ты прав.

Ответ №1:

Вы, кажется, думаете, что arr аргумент ссылается на queriesWithArgs массив, так что вы можете взять свой nextQuery оттуда. Это не так, это ссылается на исходный queries массив, и вы вызываете эти nextQuery функции без дополнительных аргументов.

Вместо этого здесь следует использовать инструмент, reduceRight не map , где nextQuery accumulator действительно будет ссылаться на предыдущий результат (или начальное значение, здесь last обратный вызов):

 const queries = [fn1, fn2, fn3, fn4];

const run = queries.reduceRight((nextQuery, queryFn) => {
    return queryFn.bind(null, nextQuery);
}, function last() {
    console.log("done");
});

run();
  

Комментарии:

1. Должно быть, это первый раз, когда я вижу, что reduceRight здесь используется по назначению. Просто странное наблюдение, я полагаю.

2. Версия обратного вызова классического трюка с обещанием reduce . 🙂

3. Фактически, предполагая, что это $.get jQuery, как кажется вероятным, вы могли бы использовать трюк promise reduce для чего-то более идиоматичного (на мой взгляд).

4. о, понял, спасибо. это просто синтетическая обучающая задача, поэтому моей целью было динамически создать что-то вроде fn1.bind(fn2.bind(fn3.bind(fn4))) и затем вызвать fn1()

5. @ЕвгенийЛитвиненко That run = fn1.bind(null, fn2.bind(null, fn3.bind(null, fn4.bind(null, last)))) is exactly what reduceRight is doing.