У меня возникли проблемы при преобразовании синхронной функции в асинхронную. существующий код, как показано ниже
$scope.getTask = function (input, id) {
var result = '';
if (condition) {
// Get all tasks.
var tasks = $scope.getAllTasks(id);
if (!angular.isUndefined(tasks)) {
var result = 'Failed';
for (var i = 0; i < tasks.length; i++) {
if (condition) {
result = 'Success';
break;
}
}
}
}
else if (condition) {
result = 'Failed';
}
else {
if (input != null || input != '') {
result = input.toLowerCase();
}
}
return result;
}
$scope.getAllTasks = function (id) {
var xhr = new XMLHttpRequest();
var url = "/api/workflow/" + id;
xhr.open("GET", url, false);
xhr.send();
return JSON.parse(xhr.responseText);
}
Но теперь мне нужно сделать это асинхронным, поэтому я пробовал использовать обещания, но это не помогло. Это не разрешается должным образом. Пожалуйста, найдите то, что я пробовал
$scope.getStatus = function (input, id) {
return new Promise((resolve, reject) => {
var result = '';
if (condition){
getAllTasks(id).then(function(response){
var tasks = response.data;
if (!angular.isUndefined(tasks)) {
var status = 'Failed';
for (var i = 0; i < tasks.length; i++) {
if (condition) {
result = 'Success';
break;
}
}
}
resolve(result);
return result;
});
resolve(result);
}
else if (condition) {
result = 'Failed';
}
else {
if (input != null || input != '') {
result = input.toLowerCase();
}
}
resolve(result);
return result;
});
}
var getAllTasks = function (id) {
const url = "/api/workflow/" + id;
return $http({method: 'GET', url})
.then((response) => {
return resolve(response)
});
}
Но это всегда возвращает [обещание объекта]. Мне нужно вернуть значение в виде строки типа «Failed» «Success». Предложите то, что мне здесь не хватает. Я знаю, что обещание вернет объект обещания из документов, но как с этим справиться.
$ scope.getStatus используется в директивах для заполнения столбцов в jquesry datatable. Фрагмент кода ниже
'sTitle': "<strong>" + $translate("list.StatusColumn") + "</strong>",
'mData': function (data, type, val) {
return $scope.getStatus(data.input, data.id);
},
'width': "16%",
'defaultContent': ""
@JaromandaX хорошо, я понял это, но есть ли способ вернуть данные вместо обещания
вернулся где? из getAllTasks? нет, он возвращает обещание (после исправления кода)
о, вы хотите, чтобы $scope.getStatus возвращал результат, а не обещание ... ну, вы не можете .. потому что асинхронный код не может возвращать результаты синхронно
вы знаете, что ваш код в настоящее время возвращает обещание, которое разрешает одно из 'Success', 'Failed' или ''
Хорошо. Есть ли способ изменить рабочий код (синхронный код) на асинхронный в этом случае?
да, верните обещание или используйте обратный вызов - в любом случае $scope.getStatus не может возвращать результат синхронно - как только вы вводите асинхронность, нет возможности "отменить" его - из-за самой природы результата, который возвращается "в непредсказуемая точка в будущем »
как вы используете / звоните $scope.getStatus? Вот где вам нужно будет внести некоторые изменения в свой код - код, который вызывает getStatus
который просто возвращает его return $ scope.getStatus (data.input, data.id); в директиве .js для заполнения столбца (запрос данных)
Итак, почему тот факт, что $scope.getStatus возвращает Promise, является проблемой?
Мне не удалось найти способ вернуть данные, находящиеся внутри обещания в методе getstatus
да, но зачем тебе это нужно ... вы просто вызываете его, используя return $scope.getStatus(data.input, data.id); ... так что это какая-то функция, которая работает с return ... значит, что-то вызывает эту другую функцию, и она ожидает результата синхронно? если это так, тогда вам нужно изменить свой код для работы с promise.then - но поскольку этот код - две функции удалены из кода, который вы опубликовали, то больше нечего сказать ... т.е. опубликуйте код у тебя проблема с - в этом случае , код - это код, который не знает, что делать с обещанием
@JaromandaX отредактировал код.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Сделай это:
Во-первых, не обрабатывайте свой http-запрос здесь, если вы обрабатываете его в своем другом обещании:
var getAllTasks = function (id) {
const url = "/api/workflow/" + id;
return $http({method: 'GET', url});
}
во-вторых: прекратите возвращать что-либо из функции обратного вызова этого обещания, поскольку вы возвращаете результат, который вы также устанавливаете в разрешении, и вы можете получить его в обработчике успеха функции then следующим образом:
$scope.getStatus = function (input, id) {
var result = '';
if (condition){
getAllTasks(id).then(function(response){
var tasks = response.data;
if (!angular.isUndefined(tasks)) {
result = 'Failed';
for (var i = 0; i < tasks.length; i++) {
if (condition) {
result = 'Success';
break;
}
}
}
return result;
});
return result;
}
else if (condition) {
result = 'Failed';
}
else {
if (input != null || input != '') {
result = input.toLowerCase();
}
}
return result;
}
console.info($scope.getStatus());
Вы можете сделать этот код более читабельным, отформатировав его лучше, чем OP ... и избегая неявного антипаттерна конструктора Promise.
Спасибо @Gaurav. Но я получаю здесь сообщение об ошибке $ scope.getStatus.then не является функцией
отредактировал мой ответ ... попробуйте еще раз. я забыл вызвать метод $ scope.getStatus.
@JaromandaX Потому что он написал некоторую логику перед отправкой результата, а не только для разрешения с использованием ответа предыдущего, поэтому я не могу увидеть неявный анти-шаблон конструктора Promise.
правильно - значит, вы говорите, что не понимаете обещаний?
Не здесь, хотя ваш код «лучше», чем OP, конечно, конструктор Promise не имеет большого значения (я понимаю, зачем вам что-то нужно), но проблема в том, что OP хочет является способом сделать так, чтобы асинхронный запрос возвращал результат синхронно ... невозможно ...
Я думаю, это будет работать в соответствии с вашими потребностями, @Eddy отредактировал код
@GauravSingh Но он всегда возвращает пустую строку. Я думаю, что это не вход в getAllTaks (Id). then (функция)
что такое «условие» в коде, проверьте его значение в консоли и почему вы используете if (condition) {} else if (condition) не является ли оно избыточным? попробуйте запустить в режиме отладки ...
@GauravSingh Условия if, else основаны на значении 'input'. Пробовал работать в режиме отладки. Но он не ждет getAllTasks (id) .then (function (response). То есть он вводит условие if, но не разрешает getAllTasks (id) .then
поэтому проверьте свой метод getalltasks (id), вы должны получить код ошибки в консоли
But this is always returning [object promise].да, это то, что возвращает Promises ... обещание - однако, поскольку вы используете его правильно, ответ.then(function(response) {здесь будет ответом, а не обещанием - извините, неправильно его использую ... удалите.then((response) => { return resolve(response) });- он не делает смысл, поскольку в getAllTasks нет функцииresolve