2017-12-05 5 views
-1

Ich möchte das Ergebnis von zwei asynchronen Funktionsaufrufen kombinieren. Ich habe versucht, das als separate Funktionen zu bekommen.Verwenden Sie das Ergebnis eines Funktionsaufrufs in der nächsten Funktion

$scope.showPage = function() { 
    var base =""; 
    var menu= ""; 
    service.getGUI('menu', function (reply) { 
      if (reply.status === 200 && reply.data !== null) {     
       menu = reply.data; 
      } 
     }); 

    service.getGUI('base', function (reply) { 
      if (reply.status === 200 && reply.data !== null) {     
       base=reply.data;     
     }); 

console.log("base:"+ base); 
console.log("menu:"+ menu); 
} 

Die Konsolenausgabe wird jedoch nicht wie erwartet aktualisiert. Wie kann ich eins nach dem anderen ausführen und das Ergebnis des ersten in der zweiten Funktion verwenden?

+0

Sie müssen sie verschachteln, der zweite sollte innerhalb des ersten Rückrufs sein. – Diego

Antwort

0

const asyncFunction = (x, cb) => setTimeout(cb.bind(null, x), 100 * Math.random()) 
 

 
// What you have 
 
asyncFunction('Async 1', console.log) 
 
asyncFunction('Async 2', console.log) 
 

 
asyncFunction('Async 3', (x) => { 
 
    console.log(x) 
 
    asyncFunction('Async 4', console.log) 
 
})
.as-console-wrapper { max-height: 100% !important; top: 0; }

Wie Sie Async 1/2 Werte werden gedruckt in einer anderen Reihenfolge jedes Mal sehen, aber Async 4 immer gedruckt nach Async 3.

0

Ihre Anrufe werden beide ASync so Es gibt keine Konsistenz für die Reihenfolge, in der die Funktionen enden. Sie können das Versprechen reduzieren -Muster verwenden, um zu warten, bis beide aufgelöst sind, bevor auf die Daten zugegriffen wird. Während das Versprechen zu reduzieren, scheint nicht die beste auf der Oberfläche, wenn Sie mit mehr als 20 asynchronen Anrufe beschäftigen Sie wissen, nicht weiter verschachteln müssen.

$scope.showPage = function() { 
    var results = { base: "", menu: "" }; 

    ['menu', 'base'].reduce(function(acc, current) { 
    return acc.then(new Promise(function(resolve, reject) => { 
     service.getGUI(current, function (reply) { 
     if (reply.status === 200 && reply.data !== null) {     
      results[current] = reply.data; 
      resolve(results); 
     } else { 
      reject("error") 
     } 
     }); 
    })); 
    }, Promise.resolve()).then(function(res) { 
    console.log(res.menu, res.base); 
    }).catch(function(e) { 
    console.log('errors have occured', e); 
    }); 
} 
0

Konvertieren Sie die Callback-basierte API auf ein Versprechen-basierte API:

function getGUIpromise(item) { 
    var deferredItem = $q.defer(); 
    service.getGUI(item, function (reply) { 
     if (reply.status === 200 && reply.data !== null) {     
      deferredItem.resolve(reply.data); 
     } else { 
      deferredItem.reject("Error with getGUI "+item); 
     }; 
    }); 
    return deferredItem.promise; 
} 

Dann $q.all verwenden für die Versprechungen warten:

$scope.showPage = function() { 
    var basePromise = getGUIpromise("base"); 
    var menuPromise = getGUIpromise("menu"); 

    $q.all({base: basePromise, menu: menuPromise}) 
    .then(function(result) { 
     console.log("base:"+ result.base); 
     console.log("menu:"+ result.menu); 
    }).catch(function(error) { 
     console.log(error); 
    }); 
}; 

Alternativ, wenn unter der Motorhaube , die service.getGUI Methode verwendet eine Versprechen-basierte API, die ursprüngliche Versprechen unter der Haube sollte zurückgegeben und verwendet werden.

Verwandte Themen