Chapo
Chapo

Reputation: 2543

write a while loop using promises using return values within the next promise

I have read all the questions on SO about this subject but I'm still stuck because the condition function in promiseWhile does not take a parameter.

My use case is the following. I am trying to query some information for some date (start_date). I do not know whether there is info for start_date in my db so I want to check for that. If there is no data, I want to query the day before and keep doing that until there is data. (I know the promise while loop is not the best way to do that but I want to learn how to do it nonetheless)

Here is my code so far

let start_date = DateTime.fromFormat(req.body.date, "yyyy-MM-dd");
let date_promise = (the_date) => {
    let the_req = {
        date: the_date
    };
    return db.query(the_req);
};

let promiseWhile = Promise.method(function (condition, action) {
    if (!condition()) return;
    return action().then(promiseWhile.bind(null, condition, action));
});

promiseWhile(
    (body) => {return body.rows.length > 0},
    () => {
        start_date = start_date.minus(luxon.Duration.fromObject({days: 1}))
        return date_promise(start_date);
    },
).then((result) => {
    // start_date ... 
    // do something with the date I've obtained
});

date_promise return a promise.

In my promiseWhile condition I am trying to test that body.rows contains something with body being the parameter of the .then function after the result of date_promise resolves. (date_promise(some_date).then((body) => {...})).

I am not sure how to proceed from there. Any help welcome.

Upvotes: 3

Views: 74

Answers (1)

Sagi Rika
Sagi Rika

Reputation: 2979

Promise.method is an older version of async functions. With that in mind and a few syntax corrections, your code would look like this:

let start_date = DateTime.fromFormat(req.body.date, "yyyy-MM-dd");

let date_promise = (the_date) => {
    let the_req = {
        date: the_date
    };
    return db.query(the_req);
};

const myAction = date => () => date_promise(date);

let promiseWhile = async function (condition, action) {
    const queryResults = await action();
    if (!condition(queryResults)) {
      start_date = start_date.minus(luxon.Duration.fromObject({days: 1}));
      return promiseWhile(condition, myAction(start_date));
    } else {
      return queryResults;
    }
};

promiseWhile(
    body => body.rows.length > 0,
    () => {
        return myAction(start_date);
    },
).then(result => { // The result you'll get here is queryResults.
    // start_date ... 
    // do something with the date I've obtained
});

Upvotes: 3

Related Questions