ユーザーセッションをチェックして、スタッフかどうかを確認する次の関数があります。今、私はこれを行うより良い方法があることを知っていますが、私はフォーラムソフトウェアと結びついたシンプルなアプリケーションを作ろうとしています。
function isStaff(callback) {
$.ajax({
url: url
}).done(function(data) {
var session = $.parseJSON(data);
if (session.is_staff === 1) {
callback(true);
} else {
callback(false);
}
});
}
「ポスト」(ハンドルバー)をコンパイルするときに、この関数をこのように使用しているとしましょう。
function compilePost(post) {
var source = $('#feed-item-template').html();
var template = Handlebars.compile(source);
var context = {
id: post.id,
content: post.text,
author: post.author,
date: $.timeago(post.date),
staff: function() {
isStaff(function(response) {
return response;
});
}
}
var html= template(context);
return html;
}
ここでの問題は、ユーザーがスタッフかどうかを確認する要求が、関数が実行されるまで要求を完了しないことです。
私はPromisesがasync:falseの代替手段であることを知っています。この場合、要求が行われ、関数が完了する前に応答が返されます。
しかし、私はこれをどのようにして約束に変換できるのかわかりません。私はそれを学ぼうとしましたが、私はその概念にこだわっています。誰かがこれを私に説明できますか?ありがとう。
まず、compilePost
関数を単純化しましょう。この関数は、同期して投稿をコンパイルする方法を知っている必要があります。 isStaff
フェッチを単純な引数に変更しましょう。
function compilePost(post, isStaff) {
var source = $('#feed-item-template').html();
var template = Handlebars.compile(source);
var context = {
id: post.id,
content: post.text,
author: post.author,
date: $.timeago(post.date),
staff: isStaff
}
var html= template(context);
return html;
}
次に、単一の目的で新しいメソッドを作成しましょう。ユーザーがスタッフのメンバーであるかどうかを確認します。
function checkForStaffMemebership() {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
success: function (data) {
var session = $.parseJSON(data);
if (session.is_staff === 1) {
resolve(true);
} else {
resolve(false);
}
}
});
});
}
この関数は、ajax
サーバーへの元の呼び出しを、$.ajax
呼び出しはサーバーから応答を取得し、ユーザーがスタッフメンバーであるかどうかにかかわらず、Promiseは回答で解決します。
これで、プロセスを調整する別の関数を記述できます。
function compilePostAsync(post) {
return checkForStaffMemebership()
.then(function (isStaff) {
return compilePost(post, isStaff);
});
}
compilePostAsync
は、ユーザーがスタッフであるかどうかを調べます。その後、投稿を編集しています。
compilePostAsync
はpromiseを返すため、以前は次のようなものがあったことに注意してください。
element.innerHTML = compilePost(post);
ここで、次のように変更する必要があります。
compilePostAsync(post).then(function (compiledPost) {
element.innerHTML = compiledPost;
});
いくつかのメモ:
isStaff
およびcheckForStaffMemebership
(オリジナルおよび新規)は引数を取得しません。userIdまたは必要なその他のデータを渡す方法を理解していると思います。documentation に従って、すでにpromiseを実装しているpromiseでajaxをラップする必要はありません。代わりに、以下で説明するように応答をチェーンします。
JQuery 1.5の時点で$ .ajax()によって返されたjqXHRオブジェクトは、Promiseインターフェースを実装し、Promiseのすべてのプロパティ、メソッド、および動作を提供します(詳細については、遅延オブジェクトを参照してください)。
レスポンスをチェーンすることで以下のようなことができます:
function isStaff(url, post) {
return $.ajax({
url: url,
dataType:"json"
}).then(function(resp){
//resp = $.parseJSON(resp); /*You dont require this if you have respose as JSON object. Just Specify it in 'dataType'*/
var source = $('#feed-item-template').html();
var template = Handlebars.compile(source);
var context = {
id: post.id,
content: post.text,
author: post.author,
date: $.timeago(post.date),
staff: resp.is_staff === 1 ? true : false
};
return template(context);
});
}
isStaff(url, post).done(function(template){
/*Your compiled template code is available here*/
}).fail(function(jqXHR, textStatus, errorThrown){
console.log("Error:"+textStatus);
});
注:error callbacks も実装してください。何がうまくいかなかったのかは決してわからないからです:)
理解のために、私はあなたの要件に似た Fiddle を作成しました。
説明:
基本的にPromiseは、非同期JSコードの同期実行を実現するために導入されています。
非同期または非同期コードとはどういう意味ですか?
実行されるコードは、即時ではない任意の時点で値を返す可能性があります。このステートメントをサポートする有名な例は、jquery ajax
です。
なぜ必要なのですか?
Promise実装は、開発者が応答を非同期コードブロックに依存する同期コードブロックを実装するのに役立ちます。 ajax呼び出しのように、サーバーにデータ文字列を要求するときに、同期コードがそれを操作してロジックを実行し、UIを更新するために、サーバーが応答データ文字列でサーバーに応答するまで待つ必要があります。
これに従ってください リンク 著者が詳細な例で説明したところ。
PS:Jquery $.defer
はpromise
をまったく異なる方法で実装またはラップします。どちらも同じ目的で使用されます。
let basedataset = {}
let ajaxbase = {};
//setting api Urls
apiinterface();
function apiinterface() {
ajaxbase.createuser = '/api/createuser'
}
//setting up payload for post method
basedataset.email = profile.getEmail()
basedataset.username = profile.getGivenName()
//setting up url for api
ajaxbase.url = ajaxbase.createuser
ajaxbase.payload = basedataset;
//reusable promise based approach
basepostmethod(ajaxbase).then(function(data) {
console.log('common data', data);
}).catch(function(reason) {
console.log('reason for rejection', reason)
});
//modular ajax (Post/GET) snippets
function basepostmethod(ajaxbase) {
return new Promise(function(resolve, reject) {
$.ajax({
url: ajaxbase.url,
method: 'post',
dataType: 'json',
data: ajaxbase.payload,
success: function(data) {
resolve(data);
},
error: function(xhr) {
reject(xhr)
}
});
});
}
Jsで非同期待機を使用するソリューションは次のようになります。
async function getMyAjaxCall() {
const someVariableName = await ajaxCallFunction();
}
function getMyAjaxCall() {
return $.ajax({
type: 'POST',
url: `someURL`,
headers: {
'Accept':'application/json',
},
success: function(response) {
// in case you need something else done.
}
});
}