元スレ+ JavaScript の質問用スレッド vol.135 +
JavaScript覧 / PC版 /みんなの評価 :
101 = :
真面目に言うと
・開示されたごく一部だけで単純な仕様ではないことがわかるのに
・全貌の情報なしに
・コードがきれいかどうかや柔軟性など曖昧な要求を回答できる人間はいない
102 = :
>View.fadeInLoadImage()
>let file = await Network.fetchFiles( )
>View.fadeOutLoadImage()
>とすると思います。
let file = await Network.fetchFiles( )
だけやればいいじゃん馬鹿なの
103 = :
>>101
具体的な細かな話は気にしなくて結構です
私が知りたいのは、皆さまが一般的にこういう問題を抱えないために使っている
オススメTask系のフレームワークだったり、普段意識してる設計パターンについての話です
コードが綺麗とか柔軟とかいうのも、厳密に定義しようとしてもらわなくて結構です
そこは私がどう感じるかではなく、皆さんが素直に自然と良いと思ってる手段を知りたいと言うだけです
104 = :
安全な近道なんて無い
> しかし、今回は下手に空回りもさせたくないという状況です
下手に空回りさせないように地道に書けとしか
F/W信奉者にありがちだが解決してくれる何かを探すのを止めてみるべき
105 = :
>>103
質問が意味わからん。最初にasyncって決めつけてるのが駄目なんじゃないの?
asyncは実装なんだからそれを使うと決めるのは最後。
実装の話は忘れて、何がしたいのか綺麗にまとめたら?
あんなごちゃごちゃしてたら読む気にもならんよ
106 = :
AとかBとか処理があるんだろ?
function process() {
A();
B();
C();
D();
B();
C();
D();
}
普通に書けばメモリリークにもならんし、
何が言いたいのかさっぱりわからない。
ここを出発点として、何が言いたいのかをまとめろ。
107 = :
あとから動作仕様変えても処理順や状態に起因するバグを起こさないパーフェクトなフレームワークはなんですか
一行にまとめるとこんなかんじ?
108 = :
いまいちよくわからんが
なんかデータ読んでる最中に(let file = await Network.fetchFiles( ))
フェードイン/フェードアウトみたいなことしてるんだけど(View.fadeInLoadImage())
読み込み中止ボタンを追加したいんだが(Cancelの概念と実装)
そんなときどうしたらいいの
って質問なんだろうか?
109 = :
そういう処理を自分で書くのは面倒だから嫌だそうだ
>全てのawait時にそれがCancelかどうかチェックして処理をするとか
>それはそれで漏らせないコードが多くなりそうですし、処理が複雑になりそうで
自分で細かく書かなくてもうまいことやってくれる何かが
希望のようだが、それをハッキリと書かないところをみると
フレームワークやライブラリ推しの書き込みの準備行動じゃねーかな
110 = :
>>104
地道に書くのは良いのですが
この先あちらもこちらもその場その場に書いていくと
メンテ面とか手に負えなくなって破綻してしまうかもしれないので
まだ取り返しの付く段階で場合によっては基礎システムを1から挿げ替えたほうが良いかもと思った次第です
>>105
現在Workerも使った大きく分けて十種類程度のタスクモジュールがあり、その中の関数の殆どが非同期もしくは並列に動いている状態です
最初はコールバックでも良いような規模で、その後async関数に切り替え、途中から自作イベント管理を追加し。。。。。。
という感じで大きくなるごとに対策してきました。
もう次に何かするなら、それで最後まで行きたいので相談させてもらっています
>>106
それで直ちに問題が会って動かなくなるというわけではないのですが、そうしたくないいくつの理由があります
・AからDまでの生存期間がそれなりに長い(ユーザーの操作次第、通常数分~数時間程度)
・BからDまでは無制限に繰り返される可能性がある(ユーザーの操作次第)
・BからDまでで大量のリソースを使い得る(通常数十MB~数百MB)
また沢山イベントハンドラやフックが残ったままになるのが気持ち悪い
(BからDまでが終われば生きた参照が無くなるのでGCによって自然と開放される)
111 = :
>>107
その通りですが、最初は問題なかったけれど複雑度が上がって無理が出てきた現状を
改善できる今より一歩上の非同期取扱概念(コツ)を知りたいと言うだけです
例えばPromiseにしてもCancellableだったりCancalTokenだったり
async generatorの代わりにObservable系を使うという手もあると思います
そういうちょっとした変更やラッパーで乗り切れるのではないかと感じています
>>108
それは例です。実際はそういうコードはありません。
メインの質問は>>97です
その例で言いたいことは、フェードアウト処理が例えば大げさに10秒かかったとします
そしたらその間にもう画面がローディング画像のフェードアウトをしていて欲しくないものになってる可能性もありますよね
1つの考え方としてはView.fadeOutLoadImage()にキャンセルできる関数を返させて、
それを関数の最後まで保持しておいて呼ぶとか考えられます
実際にそういうことをしているのですが、変数の局所性が悪くなってコードが読みづらくなります
また、その関数の終わりまでしか引き伸ばせません。もう少し先までで良いという時はイベントに登録したり煩雑になってきます。
今は場合によってはキャンセル手段を返させたり、イベントを監視させたり、セッションを確かめさせたり色々やっていますが
いかんせん一貫性がないので、その点も合わせてもっとステキな方法があるのではないかなというための例です
>>109
また自分で思いつきで書いても良いのですが、私だけのコードではないので
将来メンテする人のために少しでも良い方法を知りたい感じもちょっとはあります
112 = :
async関数が繋がるってのがまず分からない
サンプルコード位は出せないの
113 = :
頑張って説明してくれてるんだろうけど
俺の頭では理解できない
後は頼んだ
114 = :
>>112,113
繋がると言うのは
async function A ( ) { ...... await B( ) ...... }
async function B ( ) { ...... await C( ) ...... }
async function C ( ) { ...... await D( ) ...... }
のときA( )と呼んでからD( )まできた状態です
Dが解決しないとCが進みませんし
Cが進んで終わり解決しないとBが進みませんし
Bが進んで終わり解決しないとAが進まない状態です
問題はここでDから仕切り直してまたB'を呼びたいというときです
感じとしてはAがOSの起動、Bがブラウザの起動、Cがページの起動、Dがその中のプログラムスクリプトだと思ってください
OSはブラウザを起動し、もし終了したら自信も終了するよう計画します
ブラウザはページを起動し、もし終了したら自信も終了するよう計画します
ページはスクリプトを起動し、もし終了したら自信も終了するよう計画します
今したいこととは、DがB'、つまりスクリプトが新しいブラウザウィンドウを立ち上げようとしている状態です
ここで、他と同様にスクリプトがそのブラウザウィンドウの終了を待機したとしましょう
ブラウザウィンドウが無数に増え得てまずそうですよね
それでは、スクリプトがブラウザウィンドウの終了を待機しなかったとしましょう
この場合はスクリプトの処理が終わり、芋づる式にページ、ブラウザと終了します
そこまでは良いのですが、それに続けてOSも終了してしまうことになり、これは問題です
なので今取っている対策としては、Bにタスクを登録できるようにするということで、
つまりブラウザをタブ化して1つのインスタンスとし、全てのタブが閉じるまではブラウザが終了しないようにしています
それで上手く言ってるのですが、このような工夫をしないといけない箇所が段々増えてきており
危機感を感じているという次第です
115 = :
>>110
お前は自分が賢いと思ってるつもりの馬鹿だよ
基礎を何もわかっちゃいねぁ
>>106を読んで理解できてないだろ?
function process() {
A();
B();
C();
D();
B();
C();
D();
}
このコードでな、Aの中のコードの生存期間は、
Aが呼ばれた時に始まり、Aが終了すると消えるんだよ
B~Dも同じ。お前のように長い生存期間のものなんて一つもない
116 = :
>>113
わかるわけがない。
こいつは、基礎から大幅にずれた理解をしてる。
完全に間違った知識をもとに語っているから
説明全てが的外れ。
そんなのを読んで理解できるわけがないんだよ
117 = :
>>97
>>103
> 具体的な細かな話は気にしなくて結構です
あなたが解決できない原因はこれ。
理屈をすっ飛ばして、結果だけを求めるから理解できない。
ぶっちゃけ、一般的なフレームワークを使ってるという安心感が欲しいだけで理解する気は全くないでしょ?
解決手段は、配列と再帰を組み合わせるだけ
118 = :
タスクでも監視でも、これらの強制途中終了または放置が、予期しない副作用が不具合を起こす可能性をゼロにすることは不可能だろう
将来どんなコードが来るかわからんのだろ
自分でもそう思ってるけど上司の説得材料が欲しいから
こんなに長文を書いて反論で説得材料持ってきて欲しい、ってところじゃないのかね?
119 = :
ちょっと日本語文法おかしくなったがあまり気にしないでくれ
120 = :
チェーンさせるのとworkerで並列動作させるのとじゃ全然事情違くね
121 = :
>>120
>>97は並列動作じゃなくて、逐次動作じゃないの?
122 = :
123 = :
つーか非同期処理を含む関数を同期的に順次実行することを
チェーン って言うもんなんか?
124 = :
>>122
>>97を読む限り、完了をトリガーに次の処理に移っているように読めるけど、彼は並列処理の意味を理解してるのかね…
そもそも、並列処理なら、Promise.allで十分だろうに
125 = :
126 = :
なんとなく程度しか理解してないのに再設計を振られた上流SE説
127 = :
>>123
だーかーらー、
こいつは基本自体がわかってないから
用語も間違ってると考えて間違いないよ
だから難しい用語をなくして、
基本の基本の話からしないといけない
その証拠が >>115 にレスがまったくないこと
このレベルの話から自分が抱える問題につなげることができない
関係のある話だってわかってないから
128 = :
あいつが気にしてるのは、リソースの問題
関数の生存期間の話をしてるのだから
並列処理は全く関係ない話なんだよ。
ようはローカル変数がわかってないレベル
asyncとかpromiseの関係ない話をすると疲れるだけだぞ。
関係ないことを教えるだけで問題解決せずに終わるからな
129 = :
>>115,116
問題は、今回の処理は非同期で繋がっているので、
つまり、そのように並べた状態ではなく入れ子状態になっているということです
お伝い忘れてすみませんが、A->B->C->Dという関係は対等な処理を分けたものではなく
親子関係というか、包括関係と言ったらいいのですかね?とにかくそのようなものになっているのです
例えばDがメニューバーの表示とすると、
B'を再び呼び出す必要があるかどうかはDの動作にユーザーがどう反応をしたかどうかであり
勿論違う処理のケースも有るのでその結果をCで待ちわびなければなりません
実際はもう少し複雑ですが、簡単に書きますと>>114のような関係になっているということです
要するにDは下っ端も下っ端だけど、その特質上特権的な状態変化を起こす可能性があるものということなのです
>>117
私はここ何年かちょくちょくこの非同期の問題をどういう形で解決したら良いかを考えたこともあります
なので皆さんの中でよく考えて持論だったりそういうセンスを習得した人が居るのではないかと思いました
私が聞きたいのはそういう感覚であり、まさか具体的なコードに対する回答が貰えるとは思っておらず、
>>97や>>100で挙げたようなパターンに対して、ビビッとそういうときはこうするもんだという
決めつけたような適当な経験の言葉をいくらか頂けたら刺激として私に取り込もうと思ったところです
なので皆さん、適当でいいので言葉をください
例えば>>115さんは大変参考になりました
関数を小さく分割して入れ子になりがちだけど、もっと整理して単純なものに持っていけるのならそうしようと思います
130 = :
>>118,119
最後の頑張りのための気持ちを高めるためと、問題提起というわけでもないですが、
非同期処理の様々な難しさに対して皆さんがどう思考してるのかを聞きせてほしいということであります
>>123
チェーンというときはだいたいPromiseチェーンを意識しています
>>120,121,124
沢山のことを、直接的に掛けない部分もあり、事実と例えの質問を交ぜて書いた事もあって混乱させてしまいすみません
AからDまでは平行処理ではありません。沢山の非同期関数が同期的に枝分かれ状に呼び出されているルートの内の1つを選びだしたと考えてください。
実際のコードでは平行、並列の部分もありますが、ひとまずそうお考えください
131 = :
話を単純に戻して整理します
質問A)
皆さんは非同期処理が複雑になってきたらどのような対処を考えますか?
例1) コンテキストが変わると無効になるセッションをほぼ全ての関数に渡して置いて逐一セッション切れを調べるようにする
例2) キャンセルの値や手段を定義してそれを伝播させる(Cancellable Promise)
例3) その合わせ技のようなもの(CancelToken)
その他)
質問B)
>>114の状態で>>97の問題に直面したとき、
要するにいままで繋がってきた流れの中で突然安全にリセットしたくなったときはどうすればいいのか
例1) >>114で言ったように、ブラウザがほぼいつでも安全にタブを閉じれるように、
つながりの根本の方に枝を生やしたり切り落とせるポイントを用意しておく
例2) チェーンにを触れるPromiseをメモリリークを起こさないよう必死に再実装して明示的に切り離すようにする
例3) 生Promise+awaitに頼らない新設計を考える
その他)
質問C)
イベントを使うと不特定多数の直接知らない待機状態の処理を動かせて便利だが、
非同期処理のためタイミングが問題になる場合はどのような工夫をすればいいか
つまり、一方的にイベントを発火するだけではなく、それを全員がきちんと受け取って把握し
必要なら一定の準備ができたというフィードバックを得られるようなイベントシステムをきちんと整備するべきか、
それとも質問Aに書いたようなセッションだったり、今の共有状態変数を準備して対処するか
皆さんはどちらで組まれてるコードがお好きか
また他の場合でも一般に、問題解決のために高度に抽象化仕切ったシステムを作り上げたものと
例えばグローバル変数を1つ使うなどしてでも比較的シンプルに乗り切ったもの
場合によってそれらのスタンスを使い分け混合した状態
皆さんはどのスタンスで組まれてるコードがお好きか
132 = :
質問1~3)コードの正確性や安全性の検証に、コードを書くよりも圧倒的に多い工数/人数を費やす
結局、突き詰めると把握できない把握しきれない何かが問題なら
どんな状況でもコード生産速度を優先した途端に必然的に不具合が生まれる
規約が守られているか設計思想に合っているか
確認させる土壌を作るほうがマシ
133 = :
>>129
> 問題は、今回の処理は非同期で繋がっているので、
> つまり、そのように並べた状態ではなく入れ子状態になっているということです
なりません。
少なくともメモリ使用量に限っては関係ありません
134 = :
入れ子というのはこういうもののことです。
promiseやasyncではこうなりません
function process() {
A(function() {
B(function() {
C(function() {
D(function() {
B(function() {
C(function() {
D(function() {
// do something
});
});
});
});
});
});
});
}
135 = :
これ何気に書くのめんどくさそう
136 = :
並列処理と非同期の違いもわかってなさそうw
137 = :
それはある
これ非同期あんま関係ない
138 = :
>>131
> 皆さんは非同期処理が複雑になってきたらどのような対処を考えますか?
非同期処理も、非同期処理じゃない場合も同じ。
処理を単純化して、その組わせで作る
> 例1) コンテキストが変わると無効になるセッションをほぼ全ての関数に渡して置いて逐一セッション切れを調べるようにする
> 例2) キャンセルの値や手段を定義してそれを伝播させる(Cancellable Promise)
> 例3) その合わせ技のようなもの(CancelToken)
これらは非同期処理が複雑になったときの対処法ではない。
非同期処理かそうかは関係なく、処理の途中で
キャンセルしたい場合に実装すべきこと
1のセッション切れは意味不明。独自用語使うな。
何がしたいのか全く不明
139 = :
繰り返しになるけど頼むからサンプルコードで示してくれ
長々説明してくれるのは良いけど独自用語が混ざって訳分からん
140 = :
こういう人を相手に商売したらかなり稼げそう
141 = :
>>132
確かにそうでしょうが、その規約だの設計思想だのも私に委ねられてる状態でして
結局の所、コードが動かないから、不具合が生じているから質問しているわけではありません
ただ少しでも良いコードを残したい、書いていきたいと思った次第で、
私はJSの「良い」コードというのはその時その時代の世界のJSerがどう考えているかで決まると長年思っているのですが
async関数やPromiseが入って2,3年がたった今どのような「良さ」を皆さんがそこに考え出してるのか
その感覚の言葉のシャワーを浴びて私の感覚を少しでも正しい方向に矯正したいというのが正直な気持ちです
>>133,134
言葉に認識の違いがあるのかもしれませんが要するに>>114の形だとお考えください
>>137
確かにおっしゃる通りです 同期と読み替えてくださって構いません
結局私は自分の中でも問題をまとめきれて居なかった上、色々書きすぎて本質を見失っていたようです
大変申し訳ございません
実際のところ、私がこれまで書いてきた問題(>>111など)は全て繋がっていて切り離せないものだったようです
結局私は、非同期『管理システム』、そのパターンを求めているのです
142 = :
非同期と同期の大きな違いは、非同期は、同期で言う割り込みのように、
ユーザーの操作などによるイベントによる別の処理が途中と言って良いようなところで発生し得ることでしょうか
私は>>114でBで複数のCを待ちわびることで解決したと言いましたが、本当はそれだけではないのです
Cに相当する処理は実際は複数の非同期関数が繋がっているということもありますし、
その中ではawait Promise.race([D(),timeout(42),listen('buttonclick')])のようなものも使っています
ユーザー操作やタイマーや、他所から来たイベント次第でいつどう処理が完了するかは分かりません
要するに、シンプルに考えればDがBにnewC'を登録し、Dが終了すればoldCが開放されるように見えますが
実際はDが終了した段階でCはもうDを待ってはおらず、別の処理を始めているかもしれないです
Dはメニューと例えていたので変かもしれませんので言い換えると、
実際はC5が終了した段階でC4はもうC5を待ってはおらず、別の処理を始めているかもしれない、ということです
なので独自用語でセッションと言いましたが、関数開始時などに渡され、その関数が担当する処理が
未だ有効かどうか分かるオブジェクト用意し、コンテキストが変わるときにそのオブジェクトを無効状態にしておくことで、
そのような「タイミングのズレ」にだいたい対処しています
つまり、私は今基本的に素のasync-awaitを使いながら、時にはイベントを使ったり、セッションを使ったり、
Bのような部分的にタスク管理したり、色々しすぎているので
これを大きくまとめた比較的大規模なタスク管理システムを導入して整理し直すか、
もしくはそこまで行かないが10必要だったその場しのぎ対処が5になるような
比較的ちょっとした共通追加対応策についてのヒントや方向性のアドバイスが知りたいと言うことです
すみませんでした。
143 = :
>>141
あぁ、わかった
お前に言えることは「余計なことすんな」だ
問題がわかってないお前が決めた所で失敗するだけ
問題が発覚した時に、後から方向転換できるようにしていればいい。
問題が起きたときに、最初に決めたルールは絶対守れと押し付けるはやめろ
144 = :
> これを大きくまとめた比較的大規模なタスク管理システムを導入して整理し直すか、
そんなものはこの世に存在しない
大規模 = 悪 だから覚えておいたほうが良い
つまりお前の発想は間違いに突き進んでる
145 = :
「現場に聞け」じゃないの
146 = :
>>143,144
私はこれまでこのプロフェクトを2度白紙にして本当に0から作り直したのですが
この調子で行くと完成と同時くらいに3度目の限界点が来るんじゃないかなと
次の人が必要なら好きに作り直しゃ良いですっかね?
147 = :
間違いを指摘されて、本当に理解したかはともかく、それを間違いと認められる点は美徳
ただ、「あるはずだ」で質問を延々続行するのはどうかと
148 = :
>>146
反省してないからそうなる
先に問題点を洗い出せ
問題点がわかってなくて反省できるわけ無いだろ
この調子で行くと3度目じゃ終わらないだろうな
反省しないお前のやり方じゃ何度も同じことを繰り返す
要するにお前の能力不足だ
149 = :
能力不足っていうのは、プログラミング能力だけのことじゃない
不足してるのはリーダーや管理者的な能力だよ
150 = :
だいたい過去2度白紙になった原因は何よ要件変更じゃないの
どんな要件変更にも耐える設計作るのと永久機関作るのとどっちが現実的
類似してるかもしれないスレッド
- + JavaScript の質問用スレッド vol.130 + (1001) - [97%] - 2017/11/25 20:45
- + JavaScript の質問用スレッド vol.137 + (1003) - [97%] - 2019/3/26 11:46
- + JavaScript の質問用スレッド vol.130 + (974) - [97%] - 2016/10/26 14:18
- + JavaScript の質問用スレッド vol.115 + (1001) - [97%] - 2014/5/29 16:16
- + JavaScript の質問用スレッド vol.131 + (1004) - [97%] - 2018/3/7 13:30
- + JavaScript の質問用スレッド vol.132 + (1001) - [97%] - 2018/4/19 11:00
- + JavaScript の質問用スレッド vol.133 + (1001) - [97%] - 2018/6/8 10:45
- + JavaScript の質問用スレッド vol.131 + (1000) - [97%] - 2017/1/25 8:01
- + JavaScript の質問用スレッド vol.136 + (1001) - [97%] - 2019/1/8 11:30
- + JavaScript の質問用スレッド vol.134 + (1001) - [97%] - 2018/8/3 23:15
- + JavaScript の質問用スレッド vol.138 + (1004) - [97%] - 2019/4/20 23:45
- + JavaScript の質問用スレッド vol.139 + (1001) - [97%] - 2019/5/27 15:15
- + JavaScript の質問用スレッド vol.105 + (1001) - [97%] - 2013/5/20 4:45
- + JavaScript の質問用スレッド vol.125 + (1001) - [97%] - 2015/10/7 17:45
- + JavaScript の質問用スレッド vol.118 + (1002) - [95%] - 2014/8/29 22:30
- + JavaScript の質問用スレッド vol.119 + (1002) - [95%] - 2014/10/3 15:30
- + JavaScript の質問用スレッド vol.117 + (1009) - [95%] - 2014/8/5 3:30
トップメニューへ / →のくす牧場書庫について