2016-05-30 3 views
7

Мне нужно получить response.data из обещания, чтобы он мог быть возвращен закрывающей функцией. Я знаю, что, вероятно, не могу сделать это так, как я его закодировал из-за нормальной области javascript. Можно ли это сделать?Как вернуть данные с обещания

Консоль.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; 
} 

Любые указатели будут оценены.

+0

ли вы трудитесь искать на существующие вопросы по этому поводу? – Amit

+1

Нет - вы не можете - любые операции, которые вы хотите сделать с 'response', должны выполняться в обработчике' .then() '. Вы не можете писать асинхронный Javascript в синхронном стиле! – slugonamission

+1

Речь идет не о возврате данных из обещания. Второй 'console.log' происходит до того, как обещание устанавливает переменную theParentId, потому что обещание является асинхронным, а' console.log' - нет. – JordanHendrix

ответ

7

Одним из основополагающих принципов, лежащих в основе обещания, является то, что он обрабатывается асинхронно. Это означает, что вы не можете создать обещание, а затем немедленно использовать его результат синхронно в своем коде (например, невозможно вернуть результат обещания из функции, инициировавшей обещание).

Вместо этого вы должны сделать так, чтобы вернуть все обещание. Тогда любая функция, необходимая для ее результата, может называть .then() обещанием, и результат будет там, когда обещание будет разрешено.

Вот ресурс от HTML5ROCKS, который идет в течение жизненного цикла обещание, и как его выход разрешен асинхронно:
http://www.html5rocks.com/en/tutorials/es6/promises/

+1

Большое спасибо за нежное руководство. Я знал, что это будет связано с тем, как я подошел к нему. Я очень новичок в Angular, так что ударил кирпичную стену. Теперь он работает, но, возможно, он будет усовершенствован после паники. Еще раз спасибо за совет. – Craig

0

Вы должны вернуть обещание вместо переменной. Таким образом, в вашей функции просто возвращают:

return relationsManagerResource.GetParentId(nodeId) 

А потом решить возвращенное обещание. Или вы можете сделать еще один отложенный и решить theParentId.

1

Мне также не нравится использовать функцию для обработки свойства, которое было разрешено снова и снова в каждом контроллере и службе. Кажется, я не одинок: 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. Мы можем добиться этого, используя несколько способов.

  • Применение Решимость в методе маршрутизатора:

    решают: { ParentId: функция (your_factory) { your_factory.addSiteParentId(); }}

затем в контроллере и других услуг, используемых в маршрутизаторе, просто позвоните your_factory.theParentId, чтобы получить вашу собственность. Referce здесь для получения дополнительной информации: http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx

  • Используйте «запустить» метод приложения, чтобы решить вашу службу.

    app.run (функция (your_factory) {your_factory.addSiteParentId();})

  • Вводят его в первом контроллере или услуг контроллера. В контроллере мы можем вызвать все необходимые сервисы init. Затем все остаются контроллерами, так как дети основного контроллера могут получить доступ к этому свойству, как обычно.

Выбор пути зависит от вашего контекста, зависит от объема вашей переменной и частоты чтения вашей переменной.

2

Один из способов вернуть данные на обещании этого пути

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

+0

Хотя этот код может ответить на вопрос, предоставляя дополнительный контекст относительно того, почему и/или как этот код отвечает на вопрос, улучшает его долгосрочную ценность. –

+0

спасибо @DonaldDuck –

Смежные вопросы