Jake West
Jake West

Reputation: 131

How do I make a synchronous call in a recursive method?

I am trying to run a call and stop a recursive function from continuing to run before finishing another function.

I've tried to use a promise but I just don't understand what to what to put in the .then() portion as its a recursive call.

    const htmlString = '<table><tr><td>Bah</td><td>Pooh</td></tr></table>';
    const fragment = 
    document.createRange().createContextualFragment(htmlString);

    function walkTheDOM(node, func) {
        func(node);
        node = node.firstChild;
        while (node) {
            walkTheDOM(node, func);
            node = node.nextSibling;
        }
    }

    function asynchronousCallWantingtoMakeSynchronous() {
       return new Promise((resolve, reject) => {
           setTimeout(function() {
       return resolve ( console.log("should come before another recursive call"))
           }, 0)
       });
    }

    walkTheDOM(fragment, function(node) {
        console.log(node)
        asynchronousCallWantingtoMakeSynchronous.then(function(){

        })
    })

what this actually prints out:

    <table>...</table>
    <tr>...</tr>
    <td>Bah</td>
    "Bah"
    <td>Pooh</td>
    "Pooh"
    "should come before Pooh"

What I really want is:

    <table>...</table>
    "should come before another recursive call"
    <tr>...</tr>
    "should come before another recursive call"
    <td>Bah</td>
    "should come before another recursive call"
    "Bah"
    "should come before another recursive call"
    <td>Pooh</td>
    "should come before another recursive call"
    "Pooh"
    "should come before another recursive call"

Keep in mind, the setTimeout is just an example, I just want to make the asynchronous call synchronous.

Upvotes: 0

Views: 345

Answers (1)

Scott Sauyet
Scott Sauyet

Reputation: 50787

There is no way to make an asynchronous function synchronous. But you can make it feel a bit more like that with Promises or async-await. And you can use these to intersperse your calls

const htmlString = '<table><tr><td>Bah</td><td>Pooh</td></tr></table>';
const fragment = document.createRange().createContextualFragment(htmlString);

async function asyncWalkTheDOM(node, func, intersperse) {
    func(node);
    node = node.firstChild;
    while (node) {
        await intersperse(node)
        asyncWalkTheDOM(node, func, intersperse);
        node = node.nextSibling;
    }
}

async function asynchronousCall(node) {
  return new Promise(function (res, rej) { 
    setTimeout(function() {
      console.log("should come before another recursive call")
      res(node)
    }, 0)
  })
}

asyncWalkTheDOM(fragment, function(node) {
    console.log(node.nodeName)
}, asynchronousCall)

Upvotes: 1

Related Questions