$ http承诺链以错误的顺序运行

dsh*_*key 6 javascript ajax promise angularjs angular-promise

我是angularjs的新手.我的目标非常简单.我想进行ajax调用以获取数据,并且一旦完成,我想再次调用以获取依赖于第一组信息的另一组数据.

我正在尝试利用promise机制这样做,以便我可以利用链接而不是嵌套的ajax调用,并且更好地保留具有我可以根据需要绑定在一起的独立函数的能力.

我的代码类似于以下内容:

var promiseGetWorkTypes = function ($q, $scope, $http) {
	console.log("promiseGetWorkTypes");

	return $q(function (resolve, reject) {
		$http({
			method: 'GET',
			url: '/WorkTypes'
		}).then(
			function (payload) {
				console.log("Got workttypegroups")
				console.log(payload);

				$scope.WorkTypeGroups = payload.data;

				console.log("End of worktypegroups");
				resolve(payload);
			},
			function (payload) {
				reject(payload);
			});
	});
};

var promiseGetRecentActivities = function ($q, $scope, $http) {
	console.log("promiseGetRecentActivities");

	return $q(function (resolve, reject) {
		$http({
			method: 'GET',
			url: '/RecentHistory'
		}).then(
			function (payload) {
				$scope.RecentActivities = payload.data;

				resolve(payload);
			},
			// data contains the response
			// status is the HTTP status
			// headers is the header getter function
			// config is the object that was used to create the HTTP request
			function (payload) {
				reject(payload);
			});
	});
};

var index = angular.module("index", []);

index
.controller('EntitiesController', function ($scope, $http, $timeout, $q) {
	promiseGetWorkTypes($q, $http, $scope)
		.then(promiseGetRecentActivities($q, $http, $scope));
}
Run Code Online (Sandbox Code Playgroud)

但是,当我查看我的调试控制台时,我看到在"promiseGetWorkTypes"调用Ajax处理之前,对"promiseGetRecentActivities"的调用已经开始.

我在这里错过了什么或做错了什么?

Mic*_*mza 7

当你写作

promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope));
Run Code Online (Sandbox Code Playgroud)

promiseGetActivites评估此行时调用.您应该能够将调用包装到promiseGetActivities另一个函数中以延迟调用,直到第一个promise已经解决以使调用按顺序运行:

promiseGetWorkTypes($q, $http, $scope).then(function() {
  promiseGetRecentActivities($q, $http, $scope);
});
Run Code Online (Sandbox Code Playgroud)

原因与内部发生的事情无关then,而是由于Javascript语法.下列:

myFunc1(myFunc2());
Run Code Online (Sandbox Code Playgroud)

传递给myFunc1 调用的结果myFunc2(),而不是myFunc2函数的引用.从逻辑上讲,myFunc2必须先运行myFunc1.如果你写的

myFunc1(myFunc2);
Run Code Online (Sandbox Code Playgroud)

然后myFunc1会收到一个引用myFunc2,因此myFunc1会在之前运行myFunc2(事实上​​,myFunc2只有在其中的某个地方myFunc1存在调用它的代码时才会运行).

内联/匿名定义函数不会更改此行为.要将匿名函数的结果传递给另一个函数,您可以执行以下操作

myFunc1((function() {
  return 'something';
})());
Run Code Online (Sandbox Code Playgroud)

这将首先评估匿名函数,作为其返回值,'something'将传递给myFunc1.要传递对匿名函数的引用,您可以执行以下操作:

myFunc1(function() {
  return 'something';
});
Run Code Online (Sandbox Code Playgroud)

然后它将myFunc1取决于它是否会调用传递给它的函数.

将它带回您的问题,您的代码:

promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope));
Run Code Online (Sandbox Code Playgroud)

将结果传递promiseGetRecentActivities($q, $http, $scope)then,所以它必须在运行之前then运行,因此肯定不会等待承诺promiseGetWorkTypes得到解决.你似乎想要的是传递一个函数,当被调用时,运行promiseGetRecentActivities($q, $http, $scope),这是什么

promiseGetWorkTypes($q, $http, $scope).then(function() {
  promiseGetRecentActivities($q, $http, $scope);
});
Run Code Online (Sandbox Code Playgroud)

确实.

作为一个侧面说明,这似乎有点不寻常/过于复杂路过$q,$http左右等各种功能,但我想或许超出了这个问题要经过替代品的范围.