Как вернуть данные с обещаний

Мне нужно получить 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. Мы можем добиться этого, используя несколько способов.

  • Использовать разрешение в методе маршрутизатора:

    resolve: {
        parentId: function (your_factory) {
             your_factory.addSiteParentId();
        }
    }
    

затем в контроллере и других службах, используемых на вашем маршрутизаторе, просто вызовите 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();