Как сделать синхронный вызов в рекурсивном методе? - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь выполнить вызов и не допустить продолжения работы рекурсивной функции перед завершением другой функции.

Я пытался использовать обещание, но я просто не понимаю, что к чему ставитьв части .then() как рекурсивный вызов.

    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(){

        })
    })

что это на самом деле печатает:

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

Что я действительно хочу:

    <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"

Имейте в виду, setTimeout - только пример, я просто хочу сделать асинхронный вызов синхронным.

1 Ответ

1 голос
/ 17 октября 2019

Невозможно сделать асинхронную функцию синхронной. Но вы можете заставить его чувствовать себя немного больше с Promises или async-await. И вы можете использовать их, чтобы перемежать ваши звонки

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)
...