cari

Rumah  >  Soal Jawab  >  teks badan

angular.js - 怎么写promise的链式调用

比如我有一个A.func1()是异步的,它能返回一个对象x1,我还有一个B.func2()也是异步的,需要根据x1来执行,然后B.func2返回一个最终值值t,根据这个最终值t就进行一些提示性显示。请问这个要怎么写呢?
我自己写的代码是这样的

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

但是感觉这样用不用then就一个效果啦……还是变回金字塔了

高洛峰高洛峰2743 hari yang lalu508

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