2017-08-28 12 views
0

私が望む結果が得られるまで、私は約束関数でループを探しています。約束関数が結果を返すまでループ

function pull() { 
    dataFactory.pullFunction().then(function(res) { 
     pull()  
    }) 
} 

しかし、それは私に例えば私のローディングバーのためのいくつかのフロントエンド/スタイルのバグを与えている:今、私はこのような再帰を使用しているのよう

私はこのような何かをするだろう:

function pull() { 
    while (res.status == 'ONGOING') { 
     dataFactory.pullFunction().then(function(res) { 
      // my stuffs 
     }) 
    } 
} 

をしかし、私はそれをしようとするとpullFunction()が呼び出されることはありません。

+1

'(res.status == '進行中の')は'ながら - きついですループするとtrueになると非同期コードは実行されず、falseが決してtrueにならない場合はループします –

+1

多分、あなたがしたいことをもう少し詳細に記述する必要があります。 – Robert

+0

あなたの答えをありがとう、私は私の質問を編集しました – PAscalinox

答えて

0

ちょうどあなたがここに非同期操作を扱っている、あなたは伝統的なwhileforループとループにそれをすることはできませんisOngoing変数

let isOngoing = false; 
function pull() { 
    isOngoing = true; 
    dataFactory.pullFunction() 
    .then(res => { 
     if(<your-condition>) { 
     isOngoing = false; 
     } else { 
     pull(); 
     } 
    }) 
} 

編集

を作成します。あなたの環境でasync/await機能を使用できるようにしていない限り、

+0

@jkrisにお返事ありがとうございますが、再帰性を使用したくありません – PAscalinox

+0

残念ながら、私はangularjsでawaitを使用することはできません... – PAscalinox

1

async/awaitを使用できない場合は、自分自身を呼び出す関数を使用する必要があります。コールスタックが通常の(同期的な)再帰のように増えていないため、これは実際の真の再帰ではありません。

しかし、あなたは約束を守る必要があります。だから返信約束をして、残りのコードでpullの最初の呼び出しでもthenを使用してください。

おそらく、取得したデータチャンクを1つのデータセットにまとめることもできます。

ここでは、レスポンスオブジェクトがデータのチャンクを持つデータ属性を持つと仮定します。ここで

はそれが(pullFunctionのダミー実装を)うまくいく可能性がどのようである:

function pull() { 
 
    return (function loop(data) { 
 
     return dataFactory.pullFunction().then (res => { 
 
      return res.status === 'ONGOING' 
 
       ? loop(data.concat(res.data)) 
 
       : data.concat(res.data) 
 
     }); 
 
    })([]); 
 
} 
 

 
// Mock implementation 
 
var dataFactory = { 
 
    pullFunction: function() { 
 
     console.log('pull'); 
 
     return new Promise(resolve => { 
 
      setTimeout(_ => 
 
       resolve({ 
 
        status: Math.random() > 0.7 ? 'DONE' : 'ONGOING', 
 
        data: [1,2,3,4] 
 
       }), 
 
      500) 
 
     }); 
 
    } 
 
} 
 

 
// test it 
 
pull().then((data) => { 
 
    console.log('data: ', data); 
 
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

呼び出しメソッドを簡潔に保つ方法と同様です!あなたは '本当の再帰'と言いましたが、そのような学習リソースを見つけることができるかもしれない場所に私を案内することができます。 – jkris

+0

私はあなたのためのリファレンスはありませんが、 'return'式の中から' loop'を呼び出すと、 'loop'の前の呼び出しはすでに終了しています:コールバックがコールされました。したがって、ループの2つの未完呼び出しインスタンスがある瞬間はありません。これは、コールが非同期的に発生するためです。真の再帰では、呼び出しは同期的に起こります。したがって、ループの呼び出しがスタックします。最も深い呼び出しが終了すると、前の呼び出しが続きます。それはここでは起こっていません。 – trincot

関連する問題