Rumah > Soal Jawab > teks badan
比如我有一个A.func1()是异步的,它能返回一个对象x1,我还有一个B.func2()也是异步的,需要根据x1来执行,然后B.func2返回一个最终值值t,根据这个最终值t就进行一些提示性显示。请问这个要怎么写呢?
我自己写的代码是这样的
A.func1().
then(function(x1) {
B.func2(x1).
then(function(t) {
//do something
})
})
但是感觉这样用不用then就一个效果啦……还是变回金字塔了
世界只因有你2017-05-15 16:53:30
Sebagai tindak balas kepada komen tambahan dalam ulasan tentang "keadaan menyelamatkan semasa panggilan berterusan", saya ingin menghuraikan beberapa strategi
Iaitu, laraskan logik anda supaya proses panggilan A.func1, B.func2, dan fungsi tanpa nama (sebut saja func3) tidak mengandungi keadaan, iaitu, biarkan func3 hanya bergantung pada output func2 , bukan output func1; atau biarkan func2 tidak bergantung pada func1, gunakan sesuatu seperti Promise.all
untuk mendapatkan hasil func1 dan func2 pada masa yang sama dan buangnya ke func3
Kelebihan: negeri boleh dipanjangkan kepada keadaan.x2 .x3...
Masalah: Jika rantaian panggilan yang panjang mempunyai keadaan yang kompleks, ia adalah mudah untuk mencemari pepijat, dan kebolehselenggaraan kod akan dikurangkan dengan serius
Kaedah bindjs
function yourLogic() { var state = {}; return A.func1() .then(function(x1) { state.x1 = x1; return B.func2(x1); }) .then(function(t) { //play with t & state.x1 return yourResult; }); }
bluebird
boleh mengikat Arg ini dan boleh digunakan untuk mengekalkan keadaan Prinsipnya adalah sama
js
function yourLogic() { return A.func1() .bind({})//新建空对象用于保留状态 .then(function(x1) { this.x1 = x1; return B.func2(x1); }) .then(function(t) { //play with t & this.x1 return yourResult; }); }
Kelebihan: Tanpa keadaan, jika rantai panggilan panjang, keadaan tambahan ini dikawal antara dua langkah, mengekalkan kebolehselenggaraan yang lebih baik dan kurang terdedah kepada pepijat
Kelemahan: Jika setiap langkah rantai panggilan panjang mempunyai keadaan, ia akan menjadi sangat bertele-tele
js
function yourLogic() { return A.func1() .then(function(x1) { return B.func2(x1) .then(function(t) { return { t: t, x1: x1 } }); }) .then(function(state) { //play with state.t & state.x1 return yourResult; }); }
Sudah tentu, dalaman kemudian di sini juga boleh dikapsulkan dan dioptimumkan sendiri
js
function yourLogic() { return A.func1() .then(function(x1) { return keepState(B.func2(x1), { x1: x1 }, 't'); }) .then(function(state) { //play with state.t & state.x1 return yourResult; }); } function keepState(promise, state, key) { return promise.then(function(value) { state[key] = value; return state; }); }
Malah, ia adalah cara asal menulis soalan, saya rasa masalah utamanya ialah soalan itu telah diturunkan kembali kepada "neraka panggilan balik" yang asal atau memalukan piramid panggilan balik
Kelebihannya...berkesan
js
function yourLogic() { return A.func1() .then(function(x1) { return B.func2(x1) .then(function(t) { //play with t & x1 return yourResult; }); }) }
世界只因有你2017-05-15 16:53:30
Mengembalikan objek then
terus di dalam Promise
, seperti berikut:
javascript
A.func1() .then(function (x1) { return B.func2(x1); }) .then(function (t) { // do something });
Sebagai tindak balas kepada masalah yang dinyatakan dalam ulasan anda, jika anda tidak menggunakan pustaka Promise
pihak ketiga, anda boleh menggunakannya seperti berikut:
javascript
var promise = new Promise(function (resolve, reject) { var firstValue; A.func1() .then(function (x1) { firstValue = x1; // 临时保存 return B.func2(x1); }, reject) .then(function (x2) { resolve({ firstValue: firstValue, secondValue: x2 }); }, reject); }); promise.then(function (result) { console.log(result); // {"firstValue": "Hello", "secondValue": "World"} });
Menggunakan pustaka Promise
pihak ketiga boleh memudahkan proses ini.
巴扎黑2017-05-15 16:53:30
Promise akan mengembalikan objek janji, supaya ia boleh menggunakan panggilan berantai yang elegan.
过去多啦不再A梦2017-05-15 16:53:30
Jika nilai pulangan fungsi pada masa itu ialah kuantiti langsung, ia akan digunakan sebagai parameter panggilan berantai seterusnya
Jika nilai pulangan mempunyai antara muka janji, hasil keputusan janji dikembalikan
Gunakan q sebagai contoh
var q = require('q');
var a = function(){
var d = q.defer();
d.resolve(1);
return d.promise;
};
a().then(function(r){
console.log(r); // 此处是1
return 2;
}).then(function(r){
console.log(r); // 此处2,是由上一个then返回的
var d = q.defer();
d.resolve(3);
return d.promise;
}).then(function(r){
console.log(r); // 此处是3,由上一个then返回的promise的resolve提供.当需要异步调用时直接return的值肯定不够用,这时就需要返回promise对象.
});