cari

Rumah  >  Soal Jawab  >  teks badan

angular.js - Cara menulis panggilan berantai janji

Sebagai contoh, saya mempunyai A.func1() yang tidak segerak dan ia boleh mengembalikan objek x1 Saya juga mempunyai B.func2() yang juga tidak segerak dan perlu dilaksanakan berdasarkan x1, dan kemudian B. .func2 mengembalikan nilai akhir t, dan beberapa paparan segera akan dilakukan berdasarkan nilai akhir ini. Bagaimana saya harus menulis ini?
Kod yang saya tulis sendiri adalah seperti ini

A.func1().
    then(function(x1) {
        B.func2(x1).
            then(function(t) {
                //do something
            })
    })

Tapi rasanya sama je kesannya sama ada guna dulu atau tidak...masih bertukar kembali menjadi piramid

高洛峰高洛峰2776 hari yang lalu539

membalas semua(4)saya akan balas

  • 世界只因有你

    世界只因有你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

    Strategi terbaik: Nyahpenyataan

    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

    Strategi pusat: status penyelenggaraan berubah "global"

    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

    js
    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; }); }
    Kaedah bind

    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; }); }

    Strategi pertengahan: penghantaran tambahan sementara

    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; }); }

    Penyelesaian terakhir: Keadaan penyelenggaraan penutupan

    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; }); }) }

    balas
    0
  • 世界只因有你

    世界只因有你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:

    javascriptvar 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.

    balas
    0
  • 巴扎黑

    巴扎黑2017-05-15 16:53:30

    Promise akan mengembalikan objek janji, supaya ia boleh menggunakan panggilan berantai yang elegan.

    balas
    0
  • 过去多啦不再A梦

    过去多啦不再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对象.
    });

    balas
    0
  • Batalbalas