#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, как кажется вероятным, вы могли бы использовать трюк promisereduce
для чего-то более идиоматичного (на мой взгляд).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 whatreduceRight
is doing.