gpt4 book ai didi

javascript - 链接多个可选异步 Ajax 请求

转载 作者:行者123 更新时间:2023-12-02 13:51:45 25 4
gpt4 key购买 nike

我正在使用 Angular 1.5.8。我的应用程序中的 View 需要相同 3 个 ajax 请求的不同组合。有些 View 需要来自所有三个端点的数据,其他 View 则需要来自两个甚至一个端点的数据。

我正在开发一个函数来管理此数据的检索,要求应用程序仅调用每个端点一次。我希望根据需要调用 ajax 请求,但仅在需要时。目前我已经创建了一个可以工作的函数,但似乎还需要改进。

以下函数包含在$rootScope中。它使用 fetchData() 函数根据请求循环访问 get 请求。检索数据时,会将其存储在全局变量 $rootScope.appData 中,然后再次调用 fetchData()。当检索到所有数据时,延迟的 promise 将得到解决,并且数据将返回到 Controller 。

$rootScope.appData = {};

$rootScope.loadAppData = function(fetch) {
var deferred = $q.defer();

function getUser() {
$http
.get('https://example.com/api/getUser')
.success(function(result){
$rootScope.appData.currentUser = result;
fetchData();
});
}

function getPricing() {
$http
.get('https://example.com/api/getPricing')
.success(function(result) {
$rootScope.appData.pricing = result;
fetchData();
});
}

function getBilling() {
$http
.get('https://example.com/api/getBilling')
.success(function(result) {
$rootScope.appData.billing = result;
fetchData();
});
}

function fetchData() {
if (fetch.user && !$rootScope.appData.currentUser) {
getUser();
} else if (fetch.pricing && !$rootScope.appData.pricing) {
getPricing();
} else if (fetch.billing && !$rootScope.appData.billing) {
getBilling();
} else {
deferred.resolve($rootScope.appData);
}
}

if ($rootScope.appData.currentUser && $rootScope.appData.pricing &&$rootScope.appData.billing) {
deferred.resolve($rootScope.appData);
} else {
fetchData();
}

return deferred.promise;
};

一个对象fetch作为属性提交,该对象显示调用哪个ajax请求。仅请求用户定价数据的$rootScope.loadAppData()调用示例如下:

$rootScope.loadAppData({user: true, pricing: true}).then(function(data){
//execute view logic.
});

我想知道:

  1. 这些函数的链接是否应该以不同的方式进行? fetchData() 函数是否足够,或者这是执行此功能的奇怪方法?
  2. 有没有办法同时调用所有需要的 Ajax 请求,但要等待所有需要的调用完成后再解决 Promise?
  3. $rootScope 中存储这样的数据是否不寻常?

我知道此函数当前无法正确处理错误。这是我在使用此代码片段之前添加的功能,但与我的问题无关。

最佳答案

不要使用 .success 方法,而是使用 .then 方法并将数据返回到其成功处理程序:

function getUserPromise() {
var promise = $http
.get('https://example.com/api/getUser')
.then( function successHandler(result) {
//return data for chaining
return result.data;
});
return promise;
}

使用服务而不是 $rootScope:

app.service("myService", function($q, $http) {

this.loadAppData = function(fetchOptions) {

//Create first promise
var promise = $q.when({});

//Chain from promise
var p2 = promise.then(function(appData) {
if (!fetchOptions.user) {
return appData;
} else {
var derivedPromise = getUserPromise()
.then(function(user) {
appData.user = user;
//return data for chaining
return appData;
});
return derivedPromise;
);
});

//chain from p2
var p3 = p2.then(function(appData) {
if (!fetchOptions.pricing) {
return appData;
} else {
var derivedPromise = getPricingPromise()
.then(function(pricing) {
appData.pricing = pricing;
//return data for chaining
return appData;
});
return derivedPromise;
);
});
        //chain from p3
var p4 = p3.then(function(appData) {
if (!fetchOptions.billing) {
return appData;
} else {
var derivedPromise = getBillingPromise()
.then(function(user) {
appData.billing = billing;
//return data for chaining
return appData;
});
return derivedPromise;
);
});

//return final promise
return p4;
}
});

上面的示例为空对象创建了一个 Promise。然后它链接三个操作。每个操作都会检查是否需要提取。如果需要,将执行获取并将结果附加到 appData 对象;如果不需要获取,则 appData 对象将传递到链中的下一个操作。

用法:

myService.loadAppData({user: true, pricing: true})
.then(function(appData){
//execute view logic.
}).catch(functon rejectHandler(errorResponse) {
console.log(errorResponse);
throw errorResponse;
});

如果任何获取操作失败,链中的后续操作将被跳过,并调用最终的拒绝处理程序。

由于调用 Promise 的 .then 方法会返回一个新的派生 Promise,因此可以轻松创建 Promise 链。可以创建任意长度的链,并且由于一个 Promise 可以用另一个 Promise 来解决(这将进一步推迟其解决),因此可以在链中的任何点暂停/推迟 Promise 的解决。这使得实现强大的 API 成为可能。 -- AngularJS $q Service API Reference - Chaining Promises

关于javascript - 链接多个可选异步 Ajax 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40981391/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com