2017-09-09 23 views
6

私は、引数として次のようなデータ構造をとるJavaScript関数の書き込みを探しています:あなたが見ることができるように再帰非同期JavaScriptが

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

は、データ構造は、オブジェクトの配列であります。各オブジェクトにはそれぞれ1つのプロパティが含まれています。これらのプロパティはそれぞれ、文字列の「値」か、値と同じ型の別の配列の「遅延」のいずれかです。

この関数は、同じ "value"文字列をコンソールに出力し、遅延の配列を同じ方法で処理する前に "delay"ごとに2秒間休止する必要があります。この関数は、任意の深さの遅延ネスティングをサポートする必要があります。上記の2レベルディープディレイネストは単なる例です。

例えばコンソールの機能の出力データは、上記の(この順番、およびのみがこの順に)すべきである:

a 
b 
c 
d 

どのようにこの機能を実装するコードを書きますか?

+0

SOはコード記述サービスではありません。 _specific_質問に尋ねたり、_特定の問題について助けを求める場所です。 [よくある質問はどうすればよいですか?](https://stackoverflow.com/help/how-to-ask) – Hamms

+0

これは特定の問題、つまり再帰的な非同期JavaScriptを使用したネストされたデータ構造の処理に関する特定の質問です。約束する。 – user2245766

+0

私は疑問符が表示されません。「この機能を実装するコードを書いてください」というメッセージが表示されます。 – Hamms

答えて

5

あなたは約束を使用することができ、非同期/のawait:async/awaitとオブジェクト非構造は、ここに再帰的に歩くと、オブジェクトを印刷するための、より読みやすいアプローチだ使い方

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

cとdの間に遅延があってはなりませんか? – Nick

+0

@heybignick質問には少し不明だったと思いますが、あなたが正しいと思います。私はanwserを編集しました。 =) –

2

ここにアイデアがあります。あなたが終わるのは、 ["a", "delay", "b", "delay", "c", "d"]

here's a working fiddleのようなvaluesアレイです。

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

これは物事を簡素化するための素晴らしいアイデアです – user2245766

+0

ありがとう!それはうまくいくが、ホセの解決策ほど雄弁ではない。 – Nick

2

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)

関連する問題