2017-12-05 22 views
-1

2つの非同期関数呼び出しの結果を結合したいとします。私はそれを別々の機能として得ようとしました。次の関数で関数呼び出しの結果を使用する

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

ただし、コンソール出力が期待通りに更新されません。私はどのようにして1つずつ実行し、2番目の機能で最初のものの結果を使用することができます。非同期3.

+0

これらをネストする必要があります。第2のコールバックは、最初の1つのコールバックの内側に配置する必要があります。 – Diego

答えて

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

関数が終了する順序は一貫していません。promise reduceパターンを使用すると、データにアクセスする前に両方が解決されるまで待つことができます。あなたが20以上の非同期呼び出しを扱っているときには、約束を減らすことが表面上最もうまく見えないかもしれませんが、入れ子にし続ける必要はありません。

$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

あなたの呼び出しは、両方がそう非同期された後、あなたは非同期1/2値が異なるため、それぞれの時間に印刷されているが、非同期4が常に印刷されて見ることができるように

0

約束ベースのAPIへのコールバックベースの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; 
} 

そして、約束を待つ$q.allを使用します。

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

代わりにボンネット下場合、service.getGUIメソッドは約束ベースのAPIを使用しているため、元々のフードの約束を返して使用する必要があります。

関連する問題