Javascript 在连续两次角度服务呼叫期间,如何中止/取消第一次呼叫的承诺?
当通过下拉项选择上的$http angular service进行两次连续服务调用时,假设第一次调用花费时间返回,第二次调用在第一次调用解析之前返回,则显示第二次项目选择的第一次调用的数据 所以,若在第一次调用解决之前再次进行服务调用,是否有任何方法中止第一次承诺 为了演示的目的,我创建了一个带有几个项目的下拉列表,我添加了明确的条件,在选择第一个项目时,它比其他项目花费的时间稍长。 所以选择第一个项目,然后立即选择第二个项目来重现场景,检查屏幕上显示的最喜爱的书籍 感谢您的帮助 服务代码:Javascript 在连续两次角度服务呼叫期间,如何中止/取消第一次呼叫的承诺?,javascript,angularjs,Javascript,Angularjs,当通过下拉项选择上的$http angular service进行两次连续服务调用时,假设第一次调用花费时间返回,第二次调用在第一次调用解析之前返回,则显示第二次项目选择的第一次调用的数据 所以,若在第一次调用解决之前再次进行服务调用,是否有任何方法中止第一次承诺 为了演示的目的,我创建了一个带有几个项目的下拉列表,我添加了明确的条件,在选择第一个项目时,它比其他项目花费的时间稍长。 所以选择第一个项目,然后立即选择第二个项目来重现场景,检查屏幕上显示的最喜爱的书籍 感谢您的帮助 服务代码: a
app.factory('bookService', function($http, $q, $timeout) {
return {
getBook: function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}));
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise.promise;
}
}
});
您可以使用以下命令等待两个或多个承诺
$q.all([promise1,promise2]),然后(function(data){……})代码>
要访问第一个承诺的数据,只需使用数据[0]
第二个承诺返回值保存在数据[1]
中,依此类推……您可以使用以下命令等待两个或多个承诺$q.all([promise1,promise2])。然后(函数(数据){……}代码>
要访问第一个承诺的数据,只需使用数据[0]
第二个承诺返回值保存在数据[1]
中,依此类推……我找到了两种方法来处理这种情况-
案例1:在服务级别创建全局$q deffer对象,并在调用$http请求之前检查此对象是否有值。如果此deffer对象具有值,则显式解析它。普朗卡代码-
服务代码:
app.factory('bookService', function($http, $q, $timeout, bookConstants) {
var service = {};
service.mypromise = null;
service.getBook = function(id) {
if (service.mypromise) {
service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
service.mypromise = null;
}
service.mypromise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
if (service.mypromise) {
service.mypromise.resolve(data.filter(function(obj) {
service.mypromise = null;
return obj.id == id
}))
}
}, timeoutSpan);
}).error(function(msg) {
service.mypromise.reject(msg);
})
return service.mypromise.promise;
}
return service;
});
$scope.getSelectedValue = function() {
var id = $scope.selitem.id
$scope.cancel();
var bookPromise = bookService.getBook(id);
$scope.requests.push(bookPromise);
bookPromise.promise.then(getBookSuccess)
.catch(errorCallback)
.finally(getBookComplete);
}
function getBookSuccess(favouriteBooks) {
if (favouriteBooks == 'User Cancelled') {
return;
}
var books = '';
angular.forEach(favouriteBooks, function(book) {
books += book.bookName + ' '
});
$scope.selectedvalues = 'Name: ' + $scope.selitem.name +
' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
}
function errorCallback(errorMsg) {
console.log('Error Message: ' + errorMsg);
}
function getBookComplete() {
console.log('getBook Has Completed!');
}
$scope.cancel = function() {
if ($scope.requests) {
angular.forEach($scope.requests, function(request) {
request.resolve('User Cancelled');
clearRequest(request);
})
}
};
var clearRequest = function(request) {
$scope.requests.splice($scope.requests.indexOf(request), 1);
};
}]);
app.factory('bookService', function($http, $q, $timeout) {
var service = {};
service.getBook = function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}))
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise;
}
return service;
});
案例2:返回$q deffer对象作为服务响应,并将其保持在控制器级别。在连续服务调用的情况下,首先检查并明确解决第一个服务调用,然后继续其他服务调用。
普朗卡代码-
示例代码:
app.factory('bookService', function($http, $q, $timeout, bookConstants) {
var service = {};
service.mypromise = null;
service.getBook = function(id) {
if (service.mypromise) {
service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
service.mypromise = null;
}
service.mypromise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
if (service.mypromise) {
service.mypromise.resolve(data.filter(function(obj) {
service.mypromise = null;
return obj.id == id
}))
}
}, timeoutSpan);
}).error(function(msg) {
service.mypromise.reject(msg);
})
return service.mypromise.promise;
}
return service;
});
$scope.getSelectedValue = function() {
var id = $scope.selitem.id
$scope.cancel();
var bookPromise = bookService.getBook(id);
$scope.requests.push(bookPromise);
bookPromise.promise.then(getBookSuccess)
.catch(errorCallback)
.finally(getBookComplete);
}
function getBookSuccess(favouriteBooks) {
if (favouriteBooks == 'User Cancelled') {
return;
}
var books = '';
angular.forEach(favouriteBooks, function(book) {
books += book.bookName + ' '
});
$scope.selectedvalues = 'Name: ' + $scope.selitem.name +
' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
}
function errorCallback(errorMsg) {
console.log('Error Message: ' + errorMsg);
}
function getBookComplete() {
console.log('getBook Has Completed!');
}
$scope.cancel = function() {
if ($scope.requests) {
angular.forEach($scope.requests, function(request) {
request.resolve('User Cancelled');
clearRequest(request);
})
}
};
var clearRequest = function(request) {
$scope.requests.splice($scope.requests.indexOf(request), 1);
};
}]);
app.factory('bookService', function($http, $q, $timeout) {
var service = {};
service.getBook = function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}))
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise;
}
return service;
});
我找到了两种处理这种情况的方法-
案例1:在服务级别创建全局$q deffer对象,并在调用$http请求之前检查此对象是否有值。如果此deffer对象具有值,则显式解析它。普朗卡代码-
服务代码:
app.factory('bookService', function($http, $q, $timeout, bookConstants) {
var service = {};
service.mypromise = null;
service.getBook = function(id) {
if (service.mypromise) {
service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
service.mypromise = null;
}
service.mypromise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
if (service.mypromise) {
service.mypromise.resolve(data.filter(function(obj) {
service.mypromise = null;
return obj.id == id
}))
}
}, timeoutSpan);
}).error(function(msg) {
service.mypromise.reject(msg);
})
return service.mypromise.promise;
}
return service;
});
$scope.getSelectedValue = function() {
var id = $scope.selitem.id
$scope.cancel();
var bookPromise = bookService.getBook(id);
$scope.requests.push(bookPromise);
bookPromise.promise.then(getBookSuccess)
.catch(errorCallback)
.finally(getBookComplete);
}
function getBookSuccess(favouriteBooks) {
if (favouriteBooks == 'User Cancelled') {
return;
}
var books = '';
angular.forEach(favouriteBooks, function(book) {
books += book.bookName + ' '
});
$scope.selectedvalues = 'Name: ' + $scope.selitem.name +
' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
}
function errorCallback(errorMsg) {
console.log('Error Message: ' + errorMsg);
}
function getBookComplete() {
console.log('getBook Has Completed!');
}
$scope.cancel = function() {
if ($scope.requests) {
angular.forEach($scope.requests, function(request) {
request.resolve('User Cancelled');
clearRequest(request);
})
}
};
var clearRequest = function(request) {
$scope.requests.splice($scope.requests.indexOf(request), 1);
};
}]);
app.factory('bookService', function($http, $q, $timeout) {
var service = {};
service.getBook = function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}))
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise;
}
return service;
});
案例2:返回$q deffer对象作为服务响应,并将其保持在控制器级别。在连续服务调用的情况下,首先检查并明确解决第一个服务调用,然后继续其他服务调用。
普朗卡代码-
示例代码:
app.factory('bookService', function($http, $q, $timeout, bookConstants) {
var service = {};
service.mypromise = null;
service.getBook = function(id) {
if (service.mypromise) {
service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
service.mypromise = null;
}
service.mypromise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
if (service.mypromise) {
service.mypromise.resolve(data.filter(function(obj) {
service.mypromise = null;
return obj.id == id
}))
}
}, timeoutSpan);
}).error(function(msg) {
service.mypromise.reject(msg);
})
return service.mypromise.promise;
}
return service;
});
$scope.getSelectedValue = function() {
var id = $scope.selitem.id
$scope.cancel();
var bookPromise = bookService.getBook(id);
$scope.requests.push(bookPromise);
bookPromise.promise.then(getBookSuccess)
.catch(errorCallback)
.finally(getBookComplete);
}
function getBookSuccess(favouriteBooks) {
if (favouriteBooks == 'User Cancelled') {
return;
}
var books = '';
angular.forEach(favouriteBooks, function(book) {
books += book.bookName + ' '
});
$scope.selectedvalues = 'Name: ' + $scope.selitem.name +
' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
}
function errorCallback(errorMsg) {
console.log('Error Message: ' + errorMsg);
}
function getBookComplete() {
console.log('getBook Has Completed!');
}
$scope.cancel = function() {
if ($scope.requests) {
angular.forEach($scope.requests, function(request) {
request.resolve('User Cancelled');
clearRequest(request);
})
}
};
var clearRequest = function(request) {
$scope.requests.splice($scope.requests.indexOf(request), 1);
};
}]);
app.factory('bookService', function($http, $q, $timeout) {
var service = {};
service.getBook = function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}))
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise;
}
return service;
});
可能有助于您仅在响应第一个请求(同步您的请求)之后触发第二个AJAX请求。为了实现这一点,您可以使用加载符号或图像禁用下拉列表,直到收到第一个请求的响应。这是一个你可以尝试的解决方案。Karthik,要求不是从用户体验的角度限制用户采取行动。如果此问题没有解决方案,这将是最后一个选项。这可能有助于您仅在响应第一个请求(同步您的请求)后触发第二个AJAX请求。为了实现这一点,您可以使用加载符号或图像禁用下拉列表,直到收到第一个请求的响应。这是一个你可以尝试的解决方案。Karthik,要求不是从用户体验的角度限制用户采取行动。如果这个问题没有解决方案,这将是最后的选择。