Examples විවිධ උදාහරණ සහිත අසින්ක් හැසිරීම පිළිබඳ වඩාත් පොදු පැහැදිලි කිරීමක් සඳහා, කරුණාකර බලන්න ශ්රිතයක් තුළ මා වෙනස් කළ පසු මගේ විචල්යය වෙනස් නොවන්නේ ඇයි? - අසමමුහුර්ත කේත යොමුව
Already ඔබ දැනටමත් ගැටලුව තේරුම් ගෙන ඇත්නම්, පහත ඇති විසඳුම් වෙත යන්න.
ගැටලුව වන්නේ
මෙම A දී Ajax සඳහා කි්රයා අසමමිතික . ඒ කියන්නේ ඉල්ලීම යැවීම (හෝ ප්රතිචාරය ලැබීම) සාමාන්ය ක්රියාත්මක කිරීමේ ප්රවාහයෙන් ඉවත් කර ගැනීමයි. ඔබගේ උදාහරණයේ දී, $.ajaxවහාම ආපසු පැමිණීම සහ ඊළඟ ප්රකාශය, return result;ඔබ successඇමතුම ලෙස හැඳින්වූ ශ්රිතය ඇමතීමට පෙර ක්රියාත්මක කරනු ලැබේ.
සමමුහුර්ත හා අසමමුහුර්ත ප්රවාහ අතර වෙනස වඩාත් පැහැදිලි කරවන ප්රතිසමයක් මෙන්න:
සමමුහුර්ත
ඔබ මිතුරෙකුට දුරකථන ඇමතුමක් ලබා දී ඔබ වෙනුවෙන් යමක් සොයා බලන ලෙස සිතන්න. එය ටික වේලාවක් ගතවනු ඇතත්, ඔබ දුරකථනයෙන් බලා අභ්යවකාශය දෙස බලා සිටී, ඔබේ මිතුරා ඔබට අවශ්ය පිළිතුර ලබා දෙන තුරු.
ඔබ "සාමාන්ය" කේතය අඩංගු ශ්රිත ඇමතුමක් ලබා ගන්නා විටත් එය සිදු වේ:
function findItem() {
var item;
while(item_not_found) {
// search
}
return item;
}
var item = findItem();
// Do something with item
doSomethingElse();
findItemක්රියාත්මක කිරීමට බොහෝ කාලයක් ගතවනු ඇතත් , පසුව එන ඕනෑම කේතයක් මඟින් ශ්රිතය ප්රති .ලය ලබා var item = findItem();දෙන තෙක් බලා සිටිය යුතුය.
අසමමුහුර්ත
ඔබ නැවතත් ඔබේ මිතුරා අමතන්නේ එකම හේතුව නිසාය. නමුත් මේ වතාවේ ඔබ ඔහුට කියන්නේ ඔබ කඩිමුඩියේ සිටින බවත් ඔහු ඔබේ ජංගම දුරකථනයට නැවත ඇමතිය යුතු බවත්ය. ඔබ එල්ලී, නිවසින් පිට වී ඔබ කිරීමට සැලසුම් කළ ඕනෑම දෙයක් කරන්න. ඔබේ මිතුරා ඔබට නැවත ඇමතුමක් ලබා දුන් පසු, ඔහු ඔබට ලබා දුන් තොරතුරු සමඟ කටයුතු කරයි.
ඔබ අජැක්ස් ඉල්ලීමක් කරන විට සිදුවන්නේ එයයි.
findItem(function(item) {
// Do something with item
});
doSomethingElse();
ප්රතිචාරය බලාපොරොත්තුවෙන් සිටිනවා වෙනුවට, ක්රියාත්මක කිරීම වහාම ක්රියාත්මක වන අතර අජැක්ස් ඇමතුමෙන් පසුව ප්රකාශය ක්රියාත්මක වේ. අවසානයේ ප්රතිචාරය ලබා ගැනීම සඳහා, ඔබ විසින් ප්රතිචාරයක් නොලැබුණු බව වරක් කියනු ලබන උත්සවයකට, ලබා callback (දැනුම් දෙයක්? ඇමතුමක් ආපසු ?). එම ඇමතුමෙන් පසුව එන ඕනෑම ප්රකාශයක් ඇමතුම ලබා ගැනීමට පෙර ක්රියාත්මක වේ.
විසඳුම්)
ජාවාස්ක්රිප්ට්හි අසමමුහුර්ත ස්වභාවය වැලඳ ගන්න! සමහර අසමමුහුර්ත මෙහෙයුම් සමමුහුර්ත සගයන් සපයන අතර ("අජැක්ස්" ද එසේ වේ), සාමාන්යයෙන් ඒවා බ්රවුසර සන්දර්භය තුළ භාවිතා කිරීම අධෛර්යමත් කරයි.
ඇයි ඔබ අහන්නේ නරක?
ජාවාස්ක්රිප්ට් බ්රව්සරයේ UI නූල් තුළ ක්රියාත්මක වන අතර ඕනෑම දිගු ක්රියාවලියක් UI අගුළු දමනු ඇත, එය ප්රතිචාර නොදක්වයි. මීට අමතරව, ජාවාස්ක්රිප්ට් ක්රියාත්මක කිරීමේ වේලාවට ඉහළ සීමාවක් ඇති අතර බ්රවුසරය පරිශීලකයාගෙන් විමසනුයේ ක්රියාත්මක කිරීම දිගටම කරගෙන යා යුතුද නැද්ද යන්නයි.
මේ සියල්ල ඇත්තෙන්ම නරක පරිශීලක අත්දැකීමකි. සෑම දෙයක්ම හොඳින් ක්රියාත්මක වේද නැද්ද යන්න පරිශීලකයාට පැවසිය නොහැක. තවද, මන්දගාමී සම්බන්ධතාවයක් ඇති පරිශීලකයින්ට එහි බලපෑම වඩාත් නරක වනු ඇත.
පහත දැක්වෙන පරිදි අපි එකිනෙකට ඉහළින් ගොඩනඟන විවිධ විසඳුම් තුනක් දෙස බලමු:
async/await(ES2017 + සමඟ පොරොන්දු, ඔබ ප්රවාහකයෙකු හෝ පුනර්ජනකය භාවිතා කරන්නේ නම් පැරණි බ්රව්සර් වලින් ලබාගත හැකිය)
- ඇමතුම් ආපසු (නෝඩයේ ජනප්රියයි)
then()(ES2015 + සමඟ පොරොන්දු , ඔබ බොහෝ පොරොන්දු පුස්තකාලවලින් එකක් භාවිතා කරන්නේ නම් පැරණි බ්රව්සර් වලින් ලබාගත හැකිය)
මේ තුනම වත්මන් බ්රව්සර් වලින් ලබා ගත හැකි අතර 7+ නෝඩ් ඇත.
ES2017 +: සමඟ පොරොන්දු async/await
2017 දී නිකුත් කරන ලද ECMAScript අනුවාදය අසමමුහුර්ත කාර්යයන් සඳහා සින්ටැක්ස් මට්ටමේ සහාය හඳුන්වා දුන්නේය . ද සහාය ඇතිව asyncහා await, ඔබ "සමමුහුර්ත ශෛලිය" තුළ අසමමිතික ලියන්න පුළුවන්. කේතය තවමත් අසමමුහුර්තයි, නමුත් කියවීම / තේරුම් ගැනීම පහසුය.
async/awaitපොරොන්දු මත ගොඩනැඟේ: asyncශ්රිතයක් සෑම විටම පොරොන්දුවක් ලබා දෙයි. awaitපොරොන්දුවක් "ලිහා ගැනීම" සහ පොරොන්දුව ප්රතික්ෂේප කළ හොත් පොරොන්දුව විසඳා ඇති වටිනාකමට හෝ දෝෂයක් ඇතිවීමට හේතු වේ.
වැදගත්: ඔබට භාවිතා කළ හැක්කේ ශ්රිතයක් awaitතුළ පමණි async. මේ මොහොතේ, ඉහළ මට්ටමේ awaitතවමත් සහාය නොදක්වන බැවින් සන්දර්භයක් ආරම්භ කිරීම සඳහා ඔබට අසමමුහුර්ත IIFE ( ක්ෂණිකව ආයාචනා කරන ලද ක්රියාකාරී ප්රකාශනය ) සෑදිය යුතුය async.
MDN ගැන asyncසහ ඔබට වැඩිදුර කියවිය හැකිය await.
ඉහත ප්රමාදයට ඉහළින් ගොඩනඟන උදාහරණයක් මෙන්න:
// Using 'superagent' which will return a promise.
var superagent = require('superagent')
// This is isn't declared as `async` because it already returns a promise
function delay() {
// `delay` returns a promise
return new Promise(function(resolve, reject) {
// Only `delay` is able to resolve or reject the promise
setTimeout(function() {
resolve(42); // After 3 seconds, resolve the promise with value 42
}, 3000);
});
}
async function getAllBooks() {
try {
// GET a list of book IDs of the current user
var bookIDs = await superagent.get('/user/books');
// wait for 3 seconds (just for the sake of this example)
await delay();
// GET information about each book
return await superagent.get('/books/ids='+JSON.stringify(bookIDs));
} catch(error) {
// If any of the awaited promises was rejected, this catch block
// would catch the rejection reason
return null;
}
}
// Start an IIFE to use `await` at the top level
(async function(){
let books = await getAllBooks();
console.log(books);
})();
වත්මන් බ්රව්සරය සහ නෝඩ් අනුවාද සඳහා සහය දක්වයි async/await. ඔබේ කේතය ප්රතිජනක යන්ත්රයේ ආධාරයෙන් (හෝ බාබෙල් වැනි පුනර්ජනන යන්ත්ර භාවිතා කරන මෙවලම්) ES5 බවට පරිවර්තනය කිරීමෙන් ඔබට පැරණි පරිසරයන්ට සහාය විය හැකිය .
ඇමතුම් ආපසු භාර ගැනීමට කාර්යයන් වලට ඉඩ දෙන්න
ඇමතුමක් යනු හුදෙක් වෙනත් ශ්රිතයකට ලබා දෙන ශ්රිතයකි. අනෙක් ශ්රිතයට එය සූදානම් වූ විට සම්මත කරන ලද ශ්රිතය ඇමතිය හැකිය. අසමමුහුර්ත ක්රියාවලියක සන්දර්භය තුළ, අසමමුහුර්ත ක්රියාවලිය සිදු කරන සෑම අවස්ථාවකදීම ඇමතුම් ලබා ගැනීම කැඳවනු ලැබේ. සාමාන්යයෙන්, ප්රති result ලය ඇමතුම වෙත යවනු ලැබේ.
ප්රශ්නයේ උදාහරණයේ දී, ඔබට fooඇමතුමක් ලබාගෙන එය successඇමතුමක් ලෙස භාවිතා කළ හැකිය . ඉතින් මේක
var result = foo();
// Code that depends on 'result'
බවට පත්වේ
foo(function(result) {
// Code that depends on 'result'
});
මෙන්න අපි "පේළිය" ශ්රිතය අර්ථ දැක්වුවද ඔබට ඕනෑම ශ්රිත යොමු කිරීමක් කළ හැකිය:
function myCallback(result) {
// Code that depends on 'result'
}
foo(myCallback);
foo එය පහත පරිදි අර්ථ දක්වා ඇත:
function foo(callback) {
$.ajax({
// ...
success: callback
});
}
callbackfooඑය අප අමතන විට අප විසින් ලබා දෙන ශ්රිතයට යොමු වන අතර අපි එය සරලවම ලබා දෙමු success. එනම්, අජැක්ස් ඉල්ලීම සාර්ථක වූ පසු, $.ajaxඇමතුමට callbackප්රතිචාරය ඇමතීම සහ සම්මත කිරීම සිදු කරනු ඇත (එය අප ඇමතීම resultඅර්ථ දැක්වූයේ මේ නිසාය).
ඇමතුම වෙත යැවීමට පෙර ඔබට ප්රතිචාරය සැකසිය හැක:
function foo(callback) {
$.ajax({
// ...
success: function(response) {
// For example, filter the response
callback(filtered_response);
}
});
}
පෙනෙන ආකාරයට වඩා කෝල්බැක් භාවිතයෙන් කේත ලිවීම පහසුය. සියල්ලට පසු, බ්රව්සරයේ ජාවාස්ක්රිප්ට් දැඩි ලෙස සිදුවීම් මත පදනම් වේ (DOM සිදුවීම්). අජැක්ස් ප්රතිචාරය ලැබීම සිදුවීමක් මිස වෙන කිසිවක් නොවේ.
ඔබට තෙවන පාර්ශවීය කේතය සමඟ වැඩ කිරීමට සිදුවන විට දුෂ්කරතා ඇතිවිය හැකි නමුත් යෙදුම් ප්රවාහය ගැන සිතීමෙන් බොහෝ ගැටලු විසඳිය හැකිය.
ES2015 +: එවකට පොරොන්දු ()
මෙම පොරොන්දුව API සම්මතයන් 6 (ES2015) නව විශේෂාංගයක්, නමුත් එය යහපත් කල් බ්රවුසරය සහාය දැනටමත්. සම්මත පොරොන්දු ඒපීඅයි ක්රියාත්මක කරන සහ අසමමුහුර්ත කාර්යයන් (උදා: බ්ලූබර්ඩ් ) භාවිතය සහ සංයුතිය ලිහිල් කිරීම සඳහා අතිරේක ක්රම සපයන බොහෝ පුස්තකාල තිබේ.
පොරොන්දු අනාගත වටිනාකම් සඳහා බහාලුම් වේ . පොරොන්දුවට වටිනාකම ලැබුණු විට (එය විසඳනු ලැබේ ) හෝ එය අවලංගු කළ විට ( ප්රතික්ෂේප කරනු ලැබේ ), මෙම අගයට ප්රවේශ වීමට කැමති එහි සියලුම “සවන්දෙන්නන්ට” එය දැනුම් දෙයි.
සරල ඇමතුම් වලට වඩා වැඩි වාසියක් නම්, ඒවා ඔබේ කේතය විසන්ධි කිරීමට ඉඩ දෙන අතර ඒවා රචනා කිරීමට පහසු වේ.
පොරොන්දුවක් භාවිතා කිරීම පිළිබඳ සරල උදාහරණයක් මෙන්න:
function delay() {
// `delay` returns a promise
return new Promise(function(resolve, reject) {
// Only `delay` is able to resolve or reject the promise
setTimeout(function() {
resolve(42); // After 3 seconds, resolve the promise with value 42
}, 3000);
});
}
delay()
.then(function(v) { // `delay` returns a promise
console.log(v); // Log the value once it is resolved
})
.catch(function(v) {
// Or do something else if it is rejected
// (it would not happen in this example, since `reject` is not called).
});
අපගේ අජැක්ස් ඇමතුමට අදාළව අපට මෙවැනි පොරොන්දු භාවිතා කළ හැකිය:
function ajax(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(this.responseText);
};
xhr.onerror = reject;
xhr.open('GET', url);
xhr.send();
});
}
ajax("/echo/json")
.then(function(result) {
// Code depending on result
})
.catch(function() {
// An error occurred
});
පොරොන්දු වූ සියලු වාසි විස්තර කිරීම මෙම පිළිතුරේ සීමාවෙන් ඔබ්බට ය, නමුත් ඔබ නව කේතයක් ලියන්නේ නම්, ඔබ ඒවා බැරෑරුම් ලෙස සලකා බැලිය යුතුය. ඔවුන් ඔබේ කේතය විශාල සාරාංශයක් හා වෙන් කිරීමක් සපයයි.
පොරොන්දු පිළිබඳ වැඩි විස්තර: HTML5 පාෂාණ - ජාවාස්ක්රිප්ට් පොරොන්දු
පැති සටහන: jQuery හි විලම්බිත වස්තු
විලම්බිත වස්තූන් යනු jQuery හි අභිරුචි පොරොන්දු ක්රියාත්මක කිරීමයි (පොරොන්දු API ප්රමිතිකරණය කිරීමට පෙර). ඔවුන් පොරොන්දු මෙන් හැසිරෙන නමුත් තරමක් වෙනස් API හෙළි කරයි.
JQuery හි සෑම අජැක්ස් ක්රමයක්ම දැනටමත් "විලම්බිත වස්තුවක්" (සැබවින්ම විලම්බිත වස්තුවක පොරොන්දුවක්) ලබා දෙයි, එය ඔබට ඔබගේ ශ්රිතයෙන් ආපසු යා හැකිය:
function ajax() {
return $.ajax(...);
}
ajax().done(function(result) {
// Code depending on result
}).fail(function() {
// An error occurred
});
පැති සටහන: පොරොන්දුව ලබා දෙන්න
පොරොන්දු සහ කල් දැමූ වස්තූන් අනාගත වටිනාකමක් සඳහා බහාලුම් පමණක් බව මතක තබා ගන්න , ඒවා වටිනාකමම නොවේ. උදාහරණයක් ලෙස, ඔබට පහත සඳහන් දේ ඇතැයි සිතමු:
function checkPassword() {
return $.ajax({
url: '/password',
data: {
username: $('#username').val(),
password: $('#password').val()
},
type: 'POST',
dataType: 'json'
});
}
if (checkPassword()) {
// Tell the user they're logged in
}
මෙම කේතය ඉහත අසමමුහුර්ත ගැටළු වරදවා වටහා ගනී. විශේෂයෙන්, $.ajax()එය ඔබගේ සේවාදායකය මත '/ රහස් පදය' පිටුව පරික්ෂා අතර කේතය කැටි නැහැ - එය ඉල්ලීම සේවාදායකය වෙත යවයි එය බලා සිටියි අතර, එය වහාම නොව jQuery Ajax විලම්බිත වස්තුව, සේවාදායකය වෙතින් ප්රතිචාරය පැමිණේ. ඒ කියන්නේ ifප්රකාශය සෑම විටම මෙම විලම්බිත වස්තුව ලබා ගැනීමටත්, එය ලෙස සලකන්නටත්, trueපරිශීලකයා ලොග් වී ඇති ආකාරයට ඉදිරියට යන්නටත් ය. හොඳ නැත.
නමුත් නිවැරදි කිරීම පහසුය:
checkPassword()
.done(function(r) {
if (r) {
// Tell the user they're logged in
} else {
// Tell the user their password was bad
}
})
.fail(function(x) {
// Tell the user something bad happened
});
නිර්දේශ නොකරයි: සමමුහුර්ත "අජැක්ස්" ඇමතුම්
මා සඳහන් කළ පරිදි, සමහර (!) අසමමුහුර්ත මෙහෙයුම් වලට සමමුහුර්ත සගයන් ඇත. මම ඒවායේ භාවිතය වෙනුවෙන් පෙනී නොසිටිමි, නමුත් සම්පූර්ණත්වය උදෙසා, ඔබ සමමුහුර්ත ඇමතුමක් කරන්නේ කෙසේද යන්න මෙන්න:
JQuery නොමැතිව
ඔබ කෙලින්ම XMLHTTPRequestවස්තුවක් භාවිතා කරන්නේ නම් , falseතෙවන තර්කය ලෙස සම්මත කරන්න .open.
jQuery
ඔබ jQuery භාවිතා කරන්නේ නම් , ඔබට asyncවිකල්පය සැකසිය හැකිය false. මෙම විකල්පය බව කරුණාවෙන් නොසලකා හරිනු jQuery 1.8 සිට. එවිට ඔබට තවමත් ඇමතුමක්success ලබා ගත හැකිය, නැතහොත් jqXHR වස්තුවෙහිresponseText දේපල වෙත පිවිසිය හැකිය :
function foo() {
var jqXHR = $.ajax({
//...
async: false
});
return jqXHR.responseText;
}
ඔබ වැනි වෙනත් ඕනෑම jQuery Ajax ක්රමය භාවිතා කරන්නේ නම් $.get, $.getJSONආදිය, ඔබට එය වෙනස් කිරීමට ඇති $.ajax(ඔබ පමණක් මානකරණ පරාමිතික ඇතුල් වෙන නිසා $.ajax).
දැනුම්දීම! සමමුහුර්ත JSONP ඉල්ලීමක් කළ නොහැක. JSONP එහි ස්වභාවය අනුව සෑම විටම අසමමුහුර්ත වේ (මෙම විකල්පය පවා නොසැලකීමට තවත් එක් හේතුවක්).