まず、これは、数千行に及ぶ非常に同期的なコードベースに非同期呼び出しを意図的に間違った方法で組み込むという非常に特殊なケースであり、現時点では「正しく行う」ための変更を行う時間がありません。これは私の全身に痛みを与えますが、現実と理想はしばしば噛み合いません。これはひどいことだとわかっています。
さて、それはさておき、どうすれば次のことが可能になるでしょうか。
function doSomething() {
var data;
function callBack(d) {
data = d;
}
myAsynchronousCall(param1, callBack);
// block here and return data when the callback is finished
return data;
}
例 (またはその欠如) はすべてライブラリやコンパイラを使用していますが、どちらもこのソリューションには適していません。UI をフリーズさせずにブロックする方法 (たとえば、コールバックが呼び出されるまで doSomething 関数を残さない) の具体的な例が必要です。JS でそのようなことが可能であれば。
ベストアンサー1
「ただ「正しい方法」でやればいいとか、そんなことは言わないで」
わかりました。でも、本当に正しいやり方でやるべきですね...
「UI をフリーズさせずにブロックする方法の具体的な例が必要です。JS でそれが可能であれば。」
いいえ、UI をブロックせずに実行中の JavaScript をブロックすることは不可能です。
data
情報が不足しているため、解決策を提示するのは難しいですが、呼び出し関数にポーリングを行わせてグローバル変数をチェックさせ、コールバックをグローバルに設定するという選択肢もあります。
function doSomething() {
// callback sets the received data to a global var
function callBack(d) {
window.data = d;
}
// start the async
myAsynchronousCall(param1, callBack);
}
// start the function
doSomething();
// make sure the global is clear
window.data = null
// start polling at an interval until the data is found at the global
var intvl = setInterval(function() {
if (window.data) {
clearInterval(intvl);
console.log(data);
}
}, 100);
これらはすべて、 を変更できることを前提としていますdoSomething()
。それが可能かどうかはわかりません。
doSomething()
変更できるのであれば、他のコールバックから呼び出されるコールバックを に渡さない理由がわかりませんが、問題が発生する前にやめたほうがよいでしょう。 ;)
ああ、どうした。正しく実行できることを示唆する例を挙げてくれたので、その解決策を示します...
function doSomething( func ) {
function callBack(d) {
func( d );
}
myAsynchronousCall(param1, callBack);
}
doSomething(function(data) {
console.log(data);
});
doSomething()
例には非同期呼び出しに渡されるコールバックが含まれているため、正しい方法はコールバックから呼び出される関数を渡すことです。
もちろん、それがコールバックが行う唯一のことであれば、func
直接渡すだけです...
myAsynchronousCall(param1, func);