2017-09-09 68 views
6

Szukam napisać funkcję JavaScript, która ma następującą strukturę danych jako argument:rekurencyjne asynchroniczny JavaScript do przetwarzania danych zagnieżdżonych struktur

let data = [ 
    {value: 'a'}, 
    {delay: [ 
    {value: 'b'}, 
    {delay: [ 
     {value: 'c'} 
    ]} 
    ]}, 
    {value: 'd'} 
]; 

Jak widać, struktura danych jest tablicą obiektów . Każdy obiekt zawiera jedną właściwość. Każda z tych właściwości jest "wartością" z łańcuchem lub "opóźnieniem" z inną tablicą tego samego typu, co jej wartość.

Funkcja powinna wydrukować do konsoli każdy ciąg "wartości" i wstrzymać na dwie sekundy dla każdego "opóźnienia" przed przetworzeniem tablicy opóźnienia w ten sam sposób. Ta funkcja powinna obsługiwać zagnieżdżanie z dowolną głębią. Przedstawione powyżej zagnieżdżanie dwóch głębokich opóźnień jest tylko przykładem.

Wyjście funkcji do konsoli dla przykładowych danych powyżej powinny być (w tej kolejności, a dopiero tej kolejności):

a 
b 
c 
d 

Jak napisać kod do wdrożenia tej funkcji?

+0

SO nie jest usługą pisania kodu; jest to miejsce, w którym można zadać pytanie _specific_ lub uzyskać pomoc dotyczącą specyficznego problemu. Zapoznaj się z [Jak zadać dobre pytanie?] (Https://stackoverflow.com/help/how-to-ask) – Hamms

+0

To jest konkretne pytanie dotyczące konkretnego problemu, a mianowicie przetwarzania zagnieżdżonych struktur danych z rekursywnym asynchronicznym JavaScript i obietnice. – user2245766

+0

Nie widzę znaku zapytania i widzę frazę "Proszę napisać kod, aby zaimplementować tę funkcję" – Hamms

Odpowiedz

5

Można użyć Promises i asynchroniczny/Oczekujcie:

let data = [ 
 
    {value: 'a'}, 
 
    {delay: [ 
 
    {value: 'b'}, 
 
    {delay: [ 
 
     {value: 'c'} 
 
    ]} 
 
    ]}, 
 
    {value: 'd'} 
 
]; 
 

 
const delay =() => new Promise(res => 
 
    setTimeout(res, 2000)) 
 

 
const recFn = async data =>{ 
 
    for(let obj of data){ 
 
    if(obj.value){ 
 
     console.log(obj.value) 
 
    } else if(obj.delay){ 
 
     await delay(); 
 
     await recFn(obj.delay) 
 
    } 
 
    } 
 
} 
 

 
recFn(data);

+0

Czy nie powinno być opóźnienia między literami cid? – Nick

+0

@heybignick Myślę, że to było trochę niejasne w pytaniu, ale myślę, że masz rację. Zmieniłem mojego anwsera. =) –

2

Oto pomysł. To, co otrzymasz, to macierz values, która będzie wyglądać tak, jak będzie wyglądać .

let data = [ 
    {value: 'a'}, 
    {delay: [ 
     {value: 'b'}, 
     {delay: [ 
     {value: 'c'} 
     ]} 
    ]}, 
    {value: 'd'} 
    ]; 

let values = []; 

while(data.length) { 
    if(typeof data[0].value !== 'undefined') { 
    values.push(data[0].value); 
    data.shift(); 
    }else { 
    values.push('delay'); 
    var delayArray = data[0].delay; 
    data.shift(); 
    data = delayArray.concat(data); 
    } 
}; 

outputDelay(values); 

function outputDelay(elements) { 
    if(!elements.length) return false; 
    if(elements[0] == "delay") { 
    setTimeout(function(){ 
     elements.shift(); 
     outputDelay(elements); 
    }, 2000); 
    } else { 
    console.log(elements[0]); 
    elements.shift(); 
    outputDelay(elements); 
    } 
} 
+1

to jest świetny pomysł, aby uprościć rzeczy – user2245766

+0

Dzięki! Działa, ale nie tak elokwentnie jak rozwiązanie Jose. – Nick

2

Korzystanie async/await i przedmiot rozpad, tutaj jest bardziej czytelny podejście do rekursywnie chodzenia i drukowanie obiektu:

let data = [ 
 
    { value: 'a' }, 
 
    { delay: [ 
 
     { value: 'b' }, 
 
     { delay: [ 
 
      { value: 'c' } 
 
     ] 
 
     } 
 
    ] 
 
    }, 
 
    { value: 'd' } 
 
] 
 

 
function sleep(ms) { 
 
    return new Promise(resolve => { 
 
    setTimeout(resolve, ms) 
 
    }) 
 
} 
 

 
async function walk(array) { 
 
    for (const { value, delay } of array) { 
 
    if (value) { 
 
     console.log(value) 
 
    } else if (delay) { 
 
     await sleep(1000) 
 
     await walk(delay) 
 
    } 
 
    } 
 
} 
 

 
walk(data)