JavaScriptのコールバックを待つことができますか?
-
22-07-2019 - |
質問
http://abeautifulsite.net/notebook/87 <からjQueryアラートダイアログライブラリを使用しようとしていますデフォルトのアラートの代わりに(私の意見ではかなりひどいように見えます)。これは素晴らしいライブラリのようですが、jConfirmライブラリの使用方法の例はありません。
このようなことをする必要があります:
function confirm() {
var result = false;
var response = false;
jConfirm('are you sure?', 'Confirmation Dialog',
function(r) {
result = r;
response = true;
return r;
});
if (response == true) {
alert(result);
return result;
}
else {
//wait for response
alert('hi');
}
}
および.netボタンからの呼び出し:
プラグインのWebサイトにコメントを投稿し(今朝)、GoogleがJavaScriptを検索し、コールバックが完了するのを待って結果なしで完了しました。
残りのjavascriptが実行される前に、コールバックを正しく使用して結果を取得する方法に関するアイデアはありますか?
ありがとう。
解決
jConfirm('are you sure?', 'Confirmation Dialog',
function(r) {
result = r;
response = true;
return r;
}
);
if (response == true) {
これは、非同期コードを使用して発生する一連のイベントの誤解を裏切っています。インラインで記述したからといって、厳密に上から下に実行するわけではありません。
- jConfirmが呼び出され、パラメータの1つとして関数を受け取り、それを記憶します。
- jConfirmは、ページにUIを表示し、すぐに戻ります。
- 「if(response == true)」行が実行されます。実際、これは「if(response)」と表示されるはずです。ブール値の比較は不要です。しかし、いずれにしても、応答はもちろん偽です。関数はあきらめて終了し、ブラウザに制御を戻します。
- ユーザーがjConfirmのUIをクリックします。
- jConfirmはアクションにジャンプして、指定した関数をコールバックするだけで、以前に記憶されています。
- ネストされた関数はレスポンスをtrueに設定しますが、 'if(response == true)'条件では何もすることができません。
「&/;応答を待つ」と書きました。代わりとして、しかし実際にそれを行うあなたが書くことができるJavaScriptコードはありません。ブラウザーが処理を進めるjConfirm UIでクリックイベントを発生させる前に、関数が戻ってブラウザーに制御を戻す必要があります。
非同期コードを同期コンテキストで動作させる方法(およびその逆)が存在します-特にスレッドとコルーチン(およびそれらの限定された関係ジェネレーター)に。ただし、JavaScriptにはこれらの機能がないため、ライブラリが使用している同期モデルまたは非同期モデルに適合するようにコードを記述する必要があります。
他のヒント
JavaScriptに大きな制限があります。コードが非同期の世界に入ると、古典的な手続き実行フローに戻る方法はありません。
あなたの例では、解決策は、応答が満たされるのを待つループを作ることです。問題は、JavaScriptが100%の処理能力を使用せずに無限にループできる命令を提供しないことです。そのため、場合によってはユーザーが実際の質問に答えられなくなるまで、ブラウザーをブロックすることになります。
ここでの唯一の解決策は、非同期モデルに固執してそれを維持することです。私のアドバイスは、非同期の作業を行う必要がある関数にコールバックを追加して、呼び出し元が関数の最後で何かを実行できるようにすることです。
function confirm(fnCallback)
{
jConfirm('are you sure?', 'Confirmation Dialog', function(r)
{
// Do something with r
fnCallback && fnCallback(r); // call the callback if provided
});
}
// in the caller
alert('begin');
confirm(function(r)
{
alert(r);
alert('end');
})
コールバックは非同期であるため(少なくとも、ユーザーが何かを行うのを待っているという意味では)、コールバック内で必要なことを処理する方が簡単かもしれません:
function confirm() {
jConfirm('are you sure?', 'Confirmation Dialog', function(r) {
if (r) doSomething();
});
}
@klogan [コメント]
こちらからこれらを入手したと思いますか?
ページに答えが表示されます:(使用法の下を見てください)
これらのメソッドは、confirm()およびprompt()と同じ値を返しません。コールバック関数を使用して、結果の値にアクセスする必要があります。 (詳細については、デモを参照してください。)
@klogan
私がやろうとしているのは、あなたが望むものを達成するための簡単な方法は本当にないということです。 手続きとイベント駆動型のプログラミングを相関させようとしています。JavaScriptでは役に立たないことがあります。
<ストライク>
最も単純な(ただし、 risky )解決策は、擬似無限ループを使用することです。ただし、 callback
が呼び出されない場合は、実際の無限ループになります。また、JavaScriptエンジンによっては、待機中のブラウザーを強制終了する場合があります。
ポイント: 最善の策は、回避することです this イベント駆動型の手続きを強制しようとする
function confirm() {
var result = false;
var response = false;
jConfirm('are you sure?', 'Confirmation Dialog',
function(r) {
result = r;
response = true;
});
while(!response) continue; // wait
return result;
}
技術的には、はいですが、ウェブサイトではそうしません。
ナラティブJavaScriptは、非同期イベントコールバックのブロック機能を有効にするJavaScript言語の小さな拡張機能です。これにより、非同期コードが見やすく読みやすくなります。
Selenium はこのテクノロジーを使用しています。
更新
JavaScript Strandsはコルーチンを追加し、 協調的なスレッド化サポート ブロッキングを有効にするJavaScript言語 非同期イベントの機能 コールバック。これにより、コードが 非同期操作を多く利用する より線形で、読みやすく、管理しやすい。 StrandsはNarrativeに基づいて構築されています Neil Mixが作成したJavaScript ナラティブJavaScriptの多くは の多くを含むストランドに残った このドキュメント。
JavaScriptでは、コードは単純に イベントが発生するまで待ちます- イベントは常に 独立した非同期イベントハンドラ。 時々これは問題ありませんが、しばしば 単純であるべきことを強制する 文のシーケンス ゆがみ。また、 機能をカプセル化する機能 呼び出し関数は コールバックハンドラを提供します。より線 中断する機能を提供し、 実行のスレッドを再開します。実行 イベントが発生したときに再開を一時停止できます 終わった。これにより、書くことができます 読みにくい非同期イベント シンプルで線形で読みやすい処理 実装をカプセル化するコード。
このような応答を取得する必要があると思います。コールバックは必要ないと思います。
function confirm() {
var response = jConfirm('are you sure?', 'Confirmation Dialog');
if (response) {
alert(result);
}
else {
//wait for response
alert('hi');
}
}
この問題の可能な解決策を思いついたと思います。私はこの記事を読んでいた: http://treasure4developer.wordpress.com/2008 / 06/23 / calling-postback-event-from-javascript /
基本的には、javascriptからポストバックを強制するという考え方です。最初はポストバックは機能するがボタンイベントを呼び出さないことがわかりましたが、記事を読んだ後、javascriptポストバックであるかどうかを検出できることがわかりました。処理を行うメソッドを呼び出すだけです
DotnetShadowについて
男が言った方法はありません!しかし...私たちが私の国(ブラジル)で言うのに使う方法、ルガンビ:
次のようなことができます:
<h:commandLink styleClass="linkValor xExcluir" value="x"
onclick="if(confirmar('Confirmar excluir.','Deseja realmente excluir este registro?', this)) return true; else return false;"
action="#{mBeanPesquisarLinhas.excluir}"/>
およびjavascript:
function confirmar(titulo, msg, elemento) {
if ($(elemento).attr('sim')) {
$(elemento).removeAttr('sim');
return true;
} else if ($(elemento).attr('nao')) {
$(elemento).removeAttr('nao');
return false;
} else {
$("#dialog-confirm").html('<p>' + msg + '</p>').dialog({
resizable : false,
height : 200,
modal : true,
title : titulo,
buttons : {
"Sim" : function() {
$(this).dialog("close");
$(elemento).attr('sim', 'sim');
$(elemento).click();
},
"Não" : function() {
$(this).dialog("close");
$(elemento).attr('nao', 'nao');
$(elemento).click();
}
}
});
}
return false;
}
同じ問題ですが、jquery-uiを使用しています。
バイ、これが誰かの助けになることを願っています。
コールバックをメッセージの送信と考えると、コードの構造が改善されます。
このことは機能します。 jQueryが必要です。
function myconfirm(kyssa, elm, e){ // neG
if(jQuery('#confirmquestion').data('result')){
var V = jQuery('#confirmquestion').data('result');
jQuery('#confirmquestion').remove();
return V == 'Y' ? true : false;
}else if(!jQuery('#confirmquestion').length){
jQuery('body').append('<div id="confirmquestion">'+
'<h4>Kinnitus</h4>'+
'<div id="kyssa">'+kyssa+'</div>'+
'<center>'+
'<button onclick="jQuery(\'#confirmquestion\').data(\'result\', \'Y\');">Jah</button> '+
'<button onclick="jQuery(\'#confirmquestion\').data(\'result\', \'N\');">Ei</button></div>'+
'</center>');
jQuery('#confirmquestion button').click(function(){
jQuery(elm).trigger(e.type);
})
}
return false;
}
onChange="if(myconfirm(\'Saada kiri: \'+jQuery(this).find(\'option:selected\').html()+\' ?\', this, event)) { ... }"
CSS
#confirmquestion{
border:1px solid #999;
background:white;
padding-bottom: 30px;
position:fixed;
width:300px;
font-size:12px;
top:45%;
left:50%;
margin-left:-150px;
}
#confirmquestion h4 {
background:blue;
color:white;
margin:0;
padding: 2px 5px;
border-bottom:#777;
text-align:center;
}
#confirmquestion #kyssa {
padding: 30px 25px;
}