Как вернуть данные с обещаний
Мне нужно получить response.data
из обещания, чтобы оно могло быть возвращено включающей функцией. Я знаю, что, вероятно, я не могу сделать это так, как я это написал, из-за нормальной области видимости JavaScript. Есть ли способ, это можно сделать?
Console.log # 1 выдает правильные данные. console.log # 2 всегда производит 'a';
function addSiteParentId(nodeId) {
var theParentId = 'a';
var parentId = relationsManagerResource.GetParentId(nodeId)
.then(function(response){
theParentId = response.data;
console.log(theParentId); // #1
});
console.log(theParentId); // #2
return theParentId;
}
Любые указатели будут оценены.
Ответы
Ответ 1
Одним из основополагающих принципов обещания является то, что он обрабатывается асинхронно. Это означает, что вы не можете создать обещание, а затем немедленно использовать его результат синхронно в своем коде (например, невозможно вернуть результат обещания из функции, которая инициировала обещание).
Вместо этого вы хотите вернуть все обещание. Тогда любая функция, необходимая для ее результата, может вызвать .then()
в обещании, и результат будет там, когда обещание будет были разрешены.
Вот ресурс из HTML5Rocks, который проходит жизненный цикл обещания и как его выход разрешается асинхронно:
http://www.html5rocks.com/en/tutorials/es6/promises/
Ответ 2
Мне также не нравится использовать функцию для обработки свойства, которое разрешается снова и снова в каждом контроллере и сервисе. Кажись я не одинок: D
Не пытался получить результат с обещанием в качестве переменной, конечно, никак. Но я нашел и использую решение ниже, чтобы получить доступ к результату как к свойству.
Во-первых, напишите результат в свойство вашего сервиса:
app.factory('your_factory',function(){
var theParentIdResult = null;
var factoryReturn = {
theParentId: theParentIdResult,
addSiteParentId : addSiteParentId
};
return factoryReturn;
function addSiteParentId(nodeId) {
var theParentId = 'a';
var parentId = relationsManagerResource.GetParentId(nodeId)
.then(function(response){
factoryReturn.theParentIdResult = response.data;
console.log(theParentId); // #1
});
}
})
Теперь нам просто нужно убедиться, что метод addSiteParentId
всегда разрешается, прежде чем мы получим доступ к свойству theParentId
. Мы можем добиться этого, используя несколько способов.
затем в контроллере и других службах, используемых на вашем маршрутизаторе, просто вызовите your_factory.theParentId, чтобы получить вашу собственность. Обратитесь сюда для получения дополнительной информации: http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx
-
Используйте метод run
приложения для разрешения вашего сервиса.
app.run(function (your_factory) { your_factory.addSiteParentId(); })
-
Введите его в первый контроллер или службы контроллера. В контроллере мы можем вызвать все необходимые службы инициализации. Тогда все оставшиеся контроллеры как дочерние элементы основного контроллера могут быть доступны к этому свойству как обычно.
Выбор ваших способов зависит от вашего контекста, зависит от области действия вашей переменной и частоты чтения вашей переменной.
Ответ 3
Один из способов вернуть данные по обещанию таким образом
const addSiteParentId = (nodeId) => {
const data = { theParentId: "" }
relationsManagerResource.GetParentId(nodeId).then((response)=> Object.assign(data, data.theParentId, response.data)/* #1 */);
return data.theParentId;
}
// Object.assign do this magic
console.log("theParentId:", addSiteParentId(nodeId))
Object.assign: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Ответ 4
Вы должны вернуть обещание вместо переменной.
Поэтому в вашей функции просто верните:
return relationsManagerResource.GetParentId(nodeId)
И позже разрешите обещанное обещание.
Или вы можете сделать еще один отложенный и разрешить с ним theParentId
.
Ответ 5
Попробуйте этот фрагмент кода в jsfiddle. Просто мои 2 цента.
var url = "https://en.wikipedia.org/api/rest_v1/page/summary/Jurisdiction";
async function c() {
let data = await f();
console.log("data:" + data);
}
function f() {
return fetch(url)
.then(function(response) {
return response.json();
}).then(function(r) {
return JSON.stringify(r);
})
}
c();