-
ID:HwoIlo さんの質問

非同期処理ってforループで回せないですよね?
再帰処理でループさせる以外に非同期処理をループ処理させる良い方法はありますか?

みんなの回答 5 件

ID:1GPerH さんの回答

なぜ回せないのか意味が分からん。普通に配列処理する時にfor使うだろ

ID:NAPGvy

すいません。混乱してました。forでループさせる場合と再帰処理でループさせる場合、両方ありましたね。

ID:2hd5Kc さんの回答

それぞれの言葉の意味を理解してから再度質問したほうがいい。

非同期処理←なんの非同期処理なのか?
再帰処理←何を?
非同期処理をループ処理させる←??????。nミリ秒ごととかに関数実行させればいいんじゃない?

とりあえず何をやりたいのか書いたほうがいい。

ID:NAPGvy

確かにおっしゃる通りですね!整理してみます!

ID:NAPGvy

(1)なんの非同期処理なのか?
→ファイル操作やDB操作に伴う更新処理です。
(2)何の再帰処理なのか?
→非同期処理させる対象の数が決まっていない処理を再帰的に処理するということです
(3)nミリ秒ごととかに関数実行させればいいんじゃない?
→それはさすがにアンチパターンではないでしょうか。。。

ID:2hd5Kc

色々書こうとしたら下の奴がなんかきちんと書いてくれてるっぽいから問題なさそう。

  1. 非同期処理にも色々あると思うが、js+鯖側で動的にやるのか、鯖内でDBに溜め込んだのを別スレッドで一定数ごとに処理していくのかとか。DB操作、ファイル操作だけなら前者で問題ないんじゃ。
  2. 非同期と再帰の部分は分けて考えてウンヌンは下の奴が書いてたからそっち見てくれ
  3. 条件ややりたい事がわからなさ過ぎてアンチパターンかどうかもこっちでは判別できない。

仮にランダムN個ある操作対象のファイルやDBを弄る場合、操作対象の整合性を保障しないといけないから非同期であろうが待ち時間が必ず生じるだろうからその辺をきちんと書いておけば別に問題ないし、簡単な事だ。

フロント側(ウェブ上)でユーザが何か操作してイベントが発生したら、バックエンド側(鯖内部)で非同期でファイル・DB操作をしたい。ただし、その対象のファイル・DB数はユーザのイベントによって変わる。ってことでしょ?

簡単簡単。

ID:NAPGvy

コメントありがとうございます。鯖内に溜め込んでおくというのは何を溜め込んでおくのでしょうか?あと、すいません。最初に書かなかったのが悪いのですがフロントからバックという話ではなく、同じ環境内で完結する際の話となります。同一マシン内で行う非同期処理の話でした。わかりづらくてすいません。

ID:2hd5Kc

たとえば、キューみたいにDBに操作対象のファイルのURIなりDBレコードの識別子を保存しといて別スレッドで、鯖の負荷を考慮しながらnミリ毎に定期実行して消してくんだよ。メルマガとかのがそれだ。今回は関係ないみたいだけどな。

後は、俺が言いたい事を書いてくれてる下のコメID:bMnCwWklPkLp、ID:PFvUxW4jEpioに聞いてくれ。

ID:bMnCwW さんの回答

jsの場合なら、つまりこういうことだよね。


  • var hoge;
    for(var i=0;i=10000;i++){
    //非同期処理
    hoge = huga();
    }
    //値がない
    console.log(hoge);

  • 非同期処理内に処理が終わった時に実行したいコールバックを書くんだよ。ライブラリが提供するような非同期処理は、最初からそういうメソッドが提供されているからそれを利用するんだね。

ID:NAPGvy

上の例ですとhuga()の引数にコールバックとして実行したい関数オブジェクトを渡してあげれば良いのですよね?そして、hugaの中の最後の処理の後で引数で渡したコールバックをループが最後の時にのみ実行するようにif文で制御すれば良いのですよね?ループか最後かどうかの判定はどのようにすれば良いですか?上の例だとfugaの引数にコールバック用の関数オブジェクトとiのカウント値を渡してあげれば良いのですかね?

ID:bMnCwW

hugaにコールバックの仕組みが用意されているならば、そういうことになるね。ただ、なにか誤解している気がするけど、例の場合は、最終的に実行したい処理が console.log(hoge)なのだから、これをコールバック内に含めるということだよ。分かってる?

ID:NAPGvy

懸念されている点は誤解していないです。hugaに該当するメソッドは自作クラス内で定義したインスタンスメソッドとなります。

ID:bMnCwW

そもそもの話で申し訳ないんだけど、非同期処理の対象は、外部ファイルや外部プログラムになるだろうから、通常はループさせるなんてことは考えない。仮に100個の値が欲しいのであれば、100ループさせるのではなく、1回のリクエストで100個の値が返るサーバー処理を実装するのが筋。つまり、ループはリクエスの無駄。
仮に対象が自分では編集できない外部APIだったしても、あまりクライアント側でガッツリループさせるっていう手法は考えられないかなー。もちろん、できるんだけどね。それでもやる気なの?

ID:NAPGvy

"仮に対象が自分では編集できない外部APIだったしても、あまりクライアント側でガッツリループさせるっていう手法は考えられないかなー。"

編集出来ない外部APIの場合でループさせずに同様の結果を得る手法というのは具体的にはどういった手法なのでしょうか?

ID:NAPGvy

"リクエスの無駄。"

このリクエストははHTTPリクエストのことでしょうか?同じ環境内のDB操作やファイル操作を行う際の非同期処理の場合はHTTPリクエストは発生しませんが、この場合でもループをさせることは避けるべきなのでしょうか?

ID:bMnCwW

>同様の結果を得る手法
一度DBなどに貯めてください。


  • >ループをさせることは避けるべきなのでしょうか?
    その判断は別としても、どちらが効率がよいか普通に考えてよ。
ID:NAPGvy

"一度DBなどに貯めてください。"
↑そのDBに貯める処理自体を非同期ループで行ってるので、それを行うと本末転倒になってしまいます。
"その判断は別としても、どちらが効率がよいか普通に考えてよ。"

HTTPリクエストが発生しない場合であれば、ループさせた方が効率は普通に考えたら良いですね。

ID:bMnCwW

分からないなら、分からないと表現すればいいのに、「それは違う」みたいな返答されると、「ああ、そうですか」としか返しようがないです。極論、あなたが違うと思うならそれが答えでいいんじゃないでしょうか。私はあなたを論破する責任も必要も持ち合わせていないので。

ID:PFvUxW

横からだけどコメ主積んでんな。最近フロント屋領域に足を踏み入れた元コーダーかうぇふデザイナーかな。

ID:PFvUxW

あとhugaの引数にコールバック関数とカウンター変数渡して対処すんのでオッケーってコメ主書いてっけど、それじゃループさせてる非同期処理の完了順序保証されてる訳じゃないから上手く行かないケースも出てくるよ。

ID:bMnCwW

>PFvUxW4jEpio
で、何しに出てきたの?
といいますか、この一連のやりとりを見て、積んでいると感じたあなたの才能に脱帽です。せっかく出てきたんなら、この後拾って答え出してあげてよ!

ID:PFvUxW

もー、すぐ怒るんだから〜。
ダメよ♡

ID:PFvUxW

携帯からだから詳細な答えは書けないけど、
とりあえずカウンター変数を引数に渡した場合はダメ。理由は最後のループ処理をおえた時にその前の処理が完了してるとは限らないから。解決策は非同期処理をラップする関数内で完了した処理の数を数えて全部の仕事が終わってることをコールバック実行時に保証してあげること。他の解決策は非同期処理の実行順序自体を保証する必要があるならfor loopとか使わないでそれぞれの非同期処理が終わるタイミングでその処理を終えたものが次の処理を呼ぶようにしてあげること。伝わりにくかったらすまん。スプラトゥーンやりながら携帯打ってるから大変なの。

ID:PFvUxW

で、コメ主はなんでhttpリクエストも発生しないような同じ環境内の非同期処理をループ実行させるのは非効率って言ってんの?

ID:NAPGvy

ありがとうございました。盲点だった部分も含めて実装方法を理解出来ました。

ID:bMnCwW

トピ主的には解決したっぽいから、回答しなくていいかな。
トピ主はまだ初学者を装っているからいいけど、PFvUxW4jEpioは知ってる風な口ぶりでずれたこと言ってるから、申し訳ないが救えない。むかつくから何がずれてるかも教えてあげない。

ID:NAPGvy

コメ主さんもありがとうございました。

ID:2hd5Kc

コメ主は、何かトリガーがあったときにコールバック関数hogeを実行する。関数を100ループさせるのではなく、その関数内で100ループさせた結果を得るのが定石と言っていて。
ID:PFvUxW4jEpioは何かの操作で完了をまたずにforでループさせると意図した結果とずれる事があるから再帰呼び出しで確実性を持たせようってことを言ってる。
だから言い合ってることがズレててID:PFvUxW4jEpioにコメ主はキレてるってことでいいんだよね?。

ID:bMnCwW

いろいろと講釈をたれた後のオチが「なんでhttpリクエストも発生しないような同じ環境内の非同期処理をループ実行させるのは非効率」っていう質問だったので、小学生にでも絡まれているのかと、ただただ恐怖です。

ID:CJSFDp

コメしゅ、ぶちギレじゃん

ID:2hd5Kc さんの回答

この話題は割りと面白いのでage

ID:aHP0m4 さんの回答

美しきヴァンパイア兄弟とヒロインの禁断のラブ・トライアングルを描いた大人気TVシリーズ第6弾!

前シーズンで、エレナはキャロラインと共にウィットモア・カレッジに入学し、ステファンとキャロラインは、ミスティック・フォールズに現れたトラベラーズと対立する中、友情を深め、衝撃の最終話では「向こう側」の崩壊により愛するものを失うことを恐れたデイモンが大惨事を起こす。

<シックス・シーズン>では、彼らが自らの内面に潜む善と悪の二面性を探り、お互いのところへと戻っていくという人生の旅路が描かれる。

マイケル・マラーキーがエンゾ役、マット・デイビスがアラリック・サルツマン役で再登場。壮大なサスペンス、ロマンスとスリルに満ちた<シックス・シーズン>は、さらにパワーアップしてあなたを釘付けにする。
ヴァンパイア・ダイアリーズ7

サムとディーンは、相次いで起きた自殺について調査しているが、不可解な点がいくつか浮上する。

まず、自殺者たちには共通点が見られないが“ゆっくりとした切腹”というおぞましい方法が同じである。

次に、自殺者は全員カトリック教会の一員で、最近告解をしたばかり。そして二人は、ある神父に疑いを掛ける。

一方、クラウリーが魔女のリーダー、オリベットを捕らえたため、ロウェナは再び魔術を使いたいと主張する。
岳飛伝the last hero

最終更新日:2016-02-03 (5,776 views)

関連するトピックス

ページ上部に戻る