我想结合两个异步函数调用的结果。我试图将其作为单独的功能。
$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);
}
但控制台输出未按预期更新。我如何逐个执行并在第二个函数中使用第一个的结果。
答案 0 :(得分: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; }
如您所见,Async 1/2值每次都以不同的顺序打印,但Async 4始终在Async 3之后打印。
答案 1 :(得分: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);
});
}
答案 2 :(得分: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,则应返回并使用原始的底层承诺。