استرداد القيمة من وظيفة مجهولة و onReadyStateChange
-
01-10-2019 - |
سؤال
لدي وظيفة أود من خلالها إعادة قيمة كسلسلة من الأحداث كلما تم النقر على زر. ومع ذلك ، لا يمكنني معرفة كيفية استرداد القيمة من onReadyStateChange. كيف يمكنني صنعه حتى أتمكن من العودة vicArray[vicID]
?
function selectVictim()
{
var vicString;
var vicArray;
var vicID;
var params = "url=queenofsheep.com/Sheep/victims.php";
var request = new ajaxRequest();
request.open("POST", "victims.php", true);
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
request.setRequestHeader("Content-Length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);
request.onreadystatechange = function ()
{
if (this.readyState == 4)
{
if (this.status == 200)
{
if (this.responseText != null )
{
vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
}
else alert("Ajax error: No data received");
}
else alert("Ajax Error: " + this.statusText);
}
}
alert(vicArray[vicID]);
}
المحلول
لا يمكنك. لك onreadystatechange
يتم استدعاء المعالج لفترة طويلة بعد، بعدما ال selectVictim
عودة الوظيفة.
ما لديك هنا هو ، إذن أن تقول ، "وظائف غير متزامنة" - أي وظائف تولد قيمة الإرجاع الخاصة بها ليس على الفور ، ولكن بعد عملية غير متزامنة معينة.
للتعامل مع هذا ، يتعين على المرء استخدام رد اتصال لتوفير قيمة الإرجاع:
function selectVictim( callback )
{
...
...
request.onreadystatechange = function() {
...
vicArray[vicID] = ...;
callback( vicArray[vicID] );
}
}
لاحظ ال callback
جدال. كل من يسمي هذه الوظيفة ، يجب أن يوفر وظيفة أخرى لهذه الوسيطة. ثم لاحظ كيف selectVictim
يستدعي رد الاتصال عندما تكون قيمة الإرجاع جاهزة.
الآن أينما تتصل selectVictim
, ، يجب عليك تعديل الكود الخاص بك من:
function someFunc()
{
doSomething();
var vic = selectVictim();
domeSomethingElseWithVictim( vic );
}
إلى:
function someFunc()
{
doSomething();
selectVictim( function( vic ) {
domeSomethingElseWithVictim( vic );
} );
}
بسيطا بما فيه الكفاية؟
نصائح أخرى
أود استخدام رد الاتصال ، حيث يمكنك تمرير الوظيفة التي يتم تشغيلها بمجرد أن تكون الاستجابة جاهزة.
يضيف callback
كبرام:
function selectVictim(callback)
وثم:
vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
if (callback) {
callback(vicID);
}
عندما تتصل بالوظيفة ، يمكنك القيام بذلك:
selectVictim(function(vicID){
console.log('This is the id: ', vicID);
});
يمكنك أيضًا تمرير الوظيفة كقيمة إذا كنت تفضل عدم القيام بذلك مباشرة. ملاحظة: يصبح الأمر صعبًا بعض الشيء إذا قمت بتقديم الكثير من الطلبات وتحتاج إلى الحفاظ على الترتيب الذي تم تقديمه به ، ولكن هناك طرق للتعامل مع ذلك.