本文介绍AngularJS中处理多个异步请求的最佳实践。通过$q.all方法可以并行执行多个Promise,并在所有任务完成后统一处理结果。文章深入解析了Promise的核心概念、与回调函数的区别,以及其作为一等对象所具备的resolve/reject约定和错误冒泡机制。
AngularJS处理多个Promise的方法
在使用AngularJS进行开发时,经常遇到需要同时处理多个异步操作(Promise)的场景。
最直观的做法是对每个Promise分别调用then方法进行处理,例如:
var app = angular.module("app",[]);
app.controller("AppCtrl", function($q. $timeout){
var one = $q.defer();
var two = $q.defer();
var three = $q.defer();
$timeout(function(){
one.resolve("one done");
}, Math.random() * 1000)
$timeout(function(){
two.resolve("two done");
}, Math.random() * 1000)
$timeout(function(){
three.resolve("three done");
}, Math.random() * 1000)
functioin success(data){
console.log(data);
}
one.promise.then(success);
two.promise.then(success);
three.promise.then(success);
})
是否存在更优的解决方案?
AngularJS提供的$q.all方法可以接收一个包含多个Promise的数组,调用方式如下:
var all = $q.all([one.promise, two.promise, three.promise]);
all.then(success);
Promise的概念与优势
那么,什么是Promise?
Promise是一种用于异步处理值的机制。它是一个对象,代表了一个函数最终可能返回的值或抛出的异常。在与远程对象交互时,可以将其视为远程对象的代理。既然Promise属于异步处理方式的一种,它与XHR或$.ajax有何不同?
JavaScript通常使用闭包或回调函数来处理非同步返回的数据,例如页面加载后的XHR请求。使用Promise允许我们像处理已返回的数据一样与其交互,而无需依赖回调函数的触发。
Angular提出的Promise旨在解决什么问题?回调函数已被使用多年,但当存在回调依赖其他回调时,调试会变得极其困难,每一步调用后都需要显式处理错误。相比之下,Promise提供了另一种抽象:函数返回Promise对象。
为什么要使用Promise?
使用Promise的主要收获之一是摆脱回调函数的固定思维逻辑。Promise使异步处理机制看起来更像同步代码,基于同步函数的逻辑,我们可以按预期捕获返回值和异常值。可以在程序的任何时刻捕捉错误,并绕过依赖程序异常的后续代码,无需过多思考同步带来的好处。因此,使用Promise的目的是:在保持代码异步运行能力的同时,获取功能组合和错误冒泡能力。
Promise是头等对象,自带了一些约定。
• 只有一个resolve或者reject会被调用到。
• 如果promise被执行或者被拒绝了,依赖于他们的处理程序仍然会被调用。
• 处理程序总是会被异步调用。