Goul
Goul

Reputation: 583

Async call with fetch not waiting to done and going right away to the then

I am trying to sequence the run of couple of functions one after the other.

The code below calculates correctly the pages but does not return anything to its caller.

const rp = require('request-promise');
const cheerio = require('cheerio');
const fetch = require('node-fetch');

async function getNumberOfPages(url) {

    const pageUrl = url + "1";
    rp(pageUrl)
    .then(function(html) {
        return fetch(pageUrl)
        .then(response => response.text())
        .then(html => {
            const entriesPerPage = 20;
            const $ = cheerio.load(html);
            let totalEntries = $(".Aa").first().text()
            let pagesNumber = Math.ceil(totalEntries / entriesPerPage);
            return pagesNumber;
            })
        })
}

Actually, the caller enters right away in B) and the console log is "Number pages: undefined".

function loadAllFeedbacks(url) {

    getNumberOfPages(url)
    // A) Get first the pages number
    .then(result => {
        console.log("Number pages: " + result);
    })
    // B) Executes this next
    .then(() => {
        rp(url)

I can't figure out why. It seems that I should do something with the fetch but don't know how.

Also wondering if there is any point to use rp and fetch together, seems one only suffices.

Thank you

Upvotes: 2

Views: 54

Answers (1)

Quentin
Quentin

Reputation: 943562

getNumberOfPages gets to the end without returning anything, so it returns a promise that resolves as undefined.

You need to explicitly return something.

async function getNumberOfPages(url) {
    const pageUrl = url + "1";
    return rp(pageUrl)
    // etc

Now, however, you are returning a promise without using await at any point. So using the async keyword is pointless.

function getNumberOfPages(url) {
    const pageUrl = url + "1";
    return rp(pageUrl)
    // etc

Or you could rewrite the function to make use of await

async function getNumberOfPages(url) {
    const pageUrl = url + "1";
    const value_never_used = await rp(pageUrl);
    const response = await fetch(pageUrl);
    const html = await response.text();
    const entriesPerPage = 20;
    const $ = cheerio.load(html);
    let totalEntries = $(".Aa").first().text();
    let pagesNumber = Math.ceil(totalEntries / entriesPerPage);
    return pagesNumber;
}

There's no point in using request-promise and node-fetch, hence value_never_used

Upvotes: 3

Related Questions