Rumah > Artikel > hujung hadapan web > Penjelasan terperinci tentang teknik Promises_javascript dalam Javascript dan AngularJS
Sebagai contoh, janji digunakan apabila halaman itu memanggil API Peta Google.
function success(position){ var cords = position.coords; console.log(coords.latitude + coords.longitude); } function error(err){ console.warn(err.code+err.message) } navigator.geolocation.getCurrentPosition(success, error);
■ Cara mengendalikan berbilang kaedah tak segerak
Bagaimana jika terdapat banyak kaedah tak segerak yang perlu dilaksanakan secara berurutan? async1(kejayaan, kegagalan), async2(kejayaan, kegagalan), ...asyncN(kejayaan, kegagalan), bagaimana untuk menanganinya?
Yang paling mudah mungkin ditulis seperti ini:
async1(function(){ async2(function(){ ... asyncN(null, null); ... }, null) }, null)
Kod di atas agak sukar untuk dikekalkan.
Kami boleh membiarkan pemberitahuan muncul selepas semua kaedah tak segerak dilaksanakan.
var counter = N; function success(){ counter--; if(counter === 0){ alert('done'); } } async1(success); async2(success); ... asyncN(success);
■ Apakah itu Janji dan Tertunda
tertunda mewakili hasil daripada operasi tak segerak, menyediakan antara muka untuk memaparkan keputusan operasi dan status, dan menyediakan contoh janji yang boleh mendapatkan hasil operasi. Ditangguh boleh mengubah status operasi.
Promise menyediakan antara muka untuk berinteraksi dengan penangguhan yang berkaitan.
Apabila membuat tertunda, ia bersamaan dengan keadaan belum selesai
Apabila kaedah penyelesaian dilaksanakan, ia bersamaan dengan keadaan diselesaikan.
Apabila kaedah penolakan dilaksanakan, ia bersamaan dengan keadaan ditolak.
Kami boleh mentakrifkan fungsi panggil balik selepas membuat tertunda dan fungsi panggil balik akan mula dilaksanakan selepas mendapat gesaan status yang diselesaikan dan ditolak. Kaedah tak segerak tidak perlu mengetahui cara fungsi panggil balik beroperasi Ia hanya perlu memberitahu fungsi panggil balik untuk memulakan pelaksanaan selepas mendapat status diselesaikan atau ditolak.
■ Penggunaan asas
→ Cipta tertunda
var myFirstDeferred = $q.defer();
Di sini, untuk myFirstDeferred yang tertunda, status belum selesai Seterusnya, apabila kaedah tak segerak dilaksanakan dengan jayanya, status menjadi diselesaikan Apabila kaedah tak segerak gagal, status akan ditolak.
→ Selesaikan atau Tolak yang tertangguh ini
Andaikan terdapat kaedah tak segerak: async(berjaya, kegagalan)
async(function(value){ myFirstDeferred.resolve(value); }, function(errorReason){ myFirstDeferred.reject(errorReason); })
Dalam AngularJS, penyelesaian dan penolakan $q tidak bergantung pada konteks, dan boleh ditulis secara kasar seperti ini:
async(myFirstDeferred.resolve, myFirstDeferred.reject);
→ Gunakan janji dalam tertunda
var myFirstPromise = myFirstDeferred.promise; myFirstPromise .then(function(data){ }, function(error){ })
tertunda boleh mempunyai banyak janji.
var anotherDeferred = $q.defer(); anotherDeferred.promise .then(function(data){ },function(error){ }) //调用异步方法 async(anotherDeferred.resolve, anotherDeferred.reject); anotherDeferred.promise .then(function(data){ }, function(error){ })
Di atas, jika kaedah asynchronous async berjaya dilaksanakan, kedua-dua kaedah kejayaan akan dipanggil.
→ Biasanya balut kaedah tak segerak ke dalam fungsi
function getData(){ var deferred = $q.defer(); async(deferred.resolve,deferred.reject); return deferred.promise; } //deferred的promise属性记录了达到resolved, reject状态所需要执行的success和error方法 var dataPromise = getData(); dataPromise .then(function(data){ console.log('success'); }, function(error){ console.log('error'); })
Bagaimana hendak menulis jika anda hanya fokus pada fungsi panggil balik kejayaan?
dataPromise .then(function(data){ console.log('success'); })
Bagaimana untuk menulis jika anda hanya menumpukan pada fungsi panggil balik ralat?
dataPromise .then(null, function(error){ console.log('error'); }) 或 dataPromise.catch(function(error){ console.log('error'); })
Bagaimana jika panggilan balik mengembalikan hasil yang sama tanpa mengira kejayaan atau kegagalan?
var finalCallback = function(){ console.log('不管回调成功或失败都返回这个结果'); }
dataPromise.then(finalCallback, finalCallback);
atau
dataPromise.finally(finalCallback);
■ Rantaian nilai
Andaikan terdapat kaedah tak segerak yang mengembalikan nilai menggunakan deferred.resolve.
function async(value){ var deferred = $q.defer(); var result = value / 2; deferred.resolve(result); return deferred.promise; }
Memandangkan apa yang dikembalikan adalah janji, kita boleh teruskan kemudian dan kemudian.
var promise = async(8) .then(function(x){ return x+1; }) .then(function(x){ return x*2; }) promise.then(function(x){ console.log(x); })
Di atas, nilai daripada resolusi menjadi parameter sebenar setiap rantai.
■ Janji merantai
function async1(value){ var deferred = $q.defer(); var result = value * 2; deferred.resolve(result); return deferred.promise; } function async2(value){ var deferred = $q.defer(); var result = value + 1; deferred.resolve(result); return deferred.promise; } var promise = async1(10) .then(function(x){ return async2(x); }) promise.then(function(x){ console.log(x); })
Sudah tentu cara yang lebih mudah dibaca untuk menulisnya ialah:
function logValue(value){ console.log(value); } async1(10) .then(async2) .then(logValue);
Nilai pulangan kaedah async1 menjadi parameter sebenar dalam kaedah kejayaan dalam kaedah itu.
Dari perspektif menangkap pengecualian, anda juga boleh menulis seperti ini:
async1() .then(async2) .then(async3) .catch(handleReject) .finally(freeResources);
■ $q.tolak(sebab)
Menggunakan kaedah ini boleh membuat penangguhan muncul dalam keadaan ralat dan memberi sebab untuk ralat.
var promise = async().then(function(value){ if(true){ return value; } else { return $q.reject('value is not satisfied'); } })
■ $q.bila(nilai)
Balas janji dengan nilai.
function getDataFromBackend(query){ var data = searchInCache(query); if(data){ return $q.when(data); } else { reutrn makeAasyncBackendCall(query); } }
■ $q.all(promisesArr)
Tunggu semua janji dilaksanakan.
var allPromise = $q.all([ async1(), async2(), ... asyncN(); ]) allProise.then(function(values){ var value1 = values[0], value2 = values[1], ... valueN = values[N]; console.log('all done'); })
Di atas adalah kandungan terperinci artikel ini saya harap ia akan membantu kajian semua orang.