Rumah  >  Artikel  >  hujung hadapan web  >  Penjelasan terperinci tentang teknik Promises_javascript dalam Javascript dan AngularJS

Penjelasan terperinci tentang teknik Promises_javascript dalam Javascript dan AngularJS

WBOY
WBOYasal
2016-05-16 15:15:591210semak imbas

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.

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn