2

i'm trying to run second query when first was resolved like so:

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]();

but still getting error TypeError: secondQuery is not a function, while requests to 1.json and 2.json works fine fn2 seems to not receive fn3 as argument. Can you explain how it works ?

4
  • What is queryFn.bind(queryFn, nextQuery); supposed to achieve? Commented Mar 16, 2019 at 10:46
  • 1
    Ah, I guess you meant queryFn.bind(null, nextQuery); or simply () => queryfn(nextQuery)? Commented Mar 16, 2019 at 10:46
  • 1
    ^^ null would make more sense as the first argument to bind there. Commented Mar 16, 2019 at 10:46
  • yes @Bergi you right. Commented Mar 16, 2019 at 10:49

1 Answer 1

2

You seem to think that the arr argument refers to the queriesWithArgs array, so that you can take your nextQuery from there. It doesn't, it refers to the original queries array and you are calling those nextQuery functions without a further argument.

Instead, the proper tool to use here is reduceRight, not map, where nextQuery accumulator will indeed refer to the previous result (or the initial value, here the last callback):

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

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

run();
Sign up to request clarification or add additional context in comments.

6 Comments

This must be the first time I've seen a reduceRight being used actually for purpose here. Just an odd observation, I suppose.
The callback version of the classic promise reduce trick. :-)
In fact, assuming this $.get is jQuery as seems likely, you could use the promise reduce trick for something a bit more idiomatic (to my mind).
oh got it, thanks. it's just a synthetic training task, so my purpose was dynamically create somehtnig like fn1.bind(fn2.bind(fn3.bind(fn4))) and then call fn1()
@ЕвгенийЛитвиненко That run = fn1.bind(null, fn2.bind(null, fn3.bind(null, fn4.bind(null, last)))) is exactly what reduceRight is doing.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.