我有一组从 $http.get 返回的对象,我需要对其执行三个不同的自主后处理。我相信我可以使用 $q.all 并行执行后处理。
我看到大量使用遵循此模式的 $timeout/setTimeout 的示例:
function doSomethingAsync() {
var deferred = $q.defer();
setTimeout(function() {
deferred.resolve('hello world');
}, 500);
return deferred.promise;
}
doSomethingAsync().then(function(val) {
console.log('Promise Resolved!', val);
});
我是 javascript 的新手,但这并不是我问题的核心。 $timeout 和 setTimeout 函数已经是异步的,因此 doSomethingAsync 只是通过返回 promise 而落空了......没有实际工作内联完成。
在下面的例子中,我不明白函数是如何在执行后立即返回 promise 的。 “return deferred.promise”会在循环完成之前执行吗?函数不会被强制先执行循环然后返回语句吗?
function doSomethingRealWorkAsync() {
var deferred = $q.defer();
//loop through the items in an array and perform some heavy lifting that will take time
deferred.resolve('Done!');
return deferred.promise;
}
doSomethingRealWorkAsync().then(function(val) {
console.log('Promise Resolved!', val);
});
我看过的每个示例都使用异步进程($timeout 或 setTimeout)来模拟正在完成的工作。真正的工作呢?如果我有多个要并行运行的长时间运行的进程怎么办?
使用上述模式会产生以下代码,但我无法想象它能正常工作。这行得通吗?如果不是,为什么?如果是,怎么办?
$scope.items = [{}];
$scope.initialized = false;
function doOneThingToItemsAsync() {
var deferred = $q.defer();
for (var i in items) {
items[i].propertyA = 'this';
}
deferred.resolve('Done with One Thing!');
return deferred.promise;
}
function doAnotherThingToItemsAsync() {
var deferred = $q.defer();
for (var i in items) {
items[i].propertyB = 'that';
}
deferred.resolve('Done with Another Thing!');
return deferred.promise;
}
function doYetAnotherThingToItemsAsync() {
var deferred = $q.defer();
for (var i in items) {
items[i].propertyC = 'I smell a cat';
}
deferred.resolve('Done with Yet Another Thing!');
return deferred.promise;
}
function getItems () {
$http.get("/api/widgets", { timeout: 0 })
.success(function (data) {
items = data.items;
$q.all([doOneThingToItemsAsync(),
doAnotherThingToItemsAsync(),
doYetAnotherThingToItemsAsync()])
.then(function(result) {
for (var i in result) {
console.log(result[i]);
}
initialized = true;
});
})
.error(function (data) {
if (data.errorMessage) {
console.log("There was a problem retrieving your data: \n" + data.errorMessage + "\nPlease try again.");
} else {
console.log("There was a problem retrieving your data. Please try again.");
}
});
}
浏览器的解释器是否评估函数返回的类型(在本例中为 promise)并允许您调用该类型的方法(例如 then、success、error)传递将在执行 deferred 时执行的回调函数.resolve、deferred.reject 等?
最佳答案
不,正如您已经意识到的那样,您需要确保在完成任何实际工作之前返回 promise 。所以在返回 promise 之前做内联工作是行不通的。
基本上这个想法是有一个内联函数,它只创建一个延迟对象并从中返回 promise ,然后有一个异步操作来完成实际工作,并且可以通过闭包访问延迟对象并可以设置它工作完成后解决。
所以你可以拿你的例子做这样的事情:
function doSomethingAsync() {
var deferred = $q.defer();
setTimeout(function() {
// do the actual work
deffered.resolve();
}, 500);
return deferred.promise;
}
doSomethingAsync().then(function() {
console.log('Promise Resolved! and work is done');
});
关于javascript - 如何使用 $q.all 跨多个异步函数处理 $http.get 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25718828/