为什么从此Promise返回数据时我未定义?

时间:2016-01-15 19:33:47

标签: javascript angularjs angular-promise

以下

data未定义返回:

function selectSearchedTicker(ticker, load) {
    var deferred = $q.defer();

    GetTickersFactory.getTickers('searched', load).then(function(data) {
        console.log('data',data);
        var tempTickers = GetTickersFactory.returnSearchedTickers();
        $rootScope.$emit("select.searched.ticker", tempTickers);
        deferred.resolve();
    });

    return deferred.promise;
}

这是GetTickersFactory.getTickers函数:

function getTickers(type, load, searchedTicker, cached) {
    type = type || 'portfolio';
    load = load || '';
    searchedTicker = searchedTicker || {};

    var deferred = $q.defer(),
        promise;

    if (cached) portfolioCached = cached;

    //other code remains same
    tickersPane = ScopeFactory.getScope('tickersPanel');

    switch (type) {
        case 'searched':
            return ApiFactory.getTickers(null, load).then(function(data) {

                //renderTickers just does logic, no more API call
                searchedTickers.that = renderTickers(data.data.tickers, searchedTicker, 'searched');
                promise = searchedTickers.that;
                console.log('promise',promise); // <-- there is data here
                deferred.resolve(promise);
                // return returnData(searchedTickers.that);
            });
            break; // <-- after hitting this break, chrome tools hits the Angular code
        //...
    }

    return deferred.promise; // <- also tried return promise

    // other functions...
}

当我记录时,您可以看到上面的promise = searchedTickers.that;,我看到我想要在其中返回的数据。但是它永远不会回到我原来的selectSearchedTicker函数。

更新:添加了此代码,它在所有内容之前,我必须创建一个promise链,因为我需要等到TickersSelectFactory.selectSearchedTicker被调用并且这些操作的结果完成之前我打电话给2 $emit

TickersSelectFactory.selectSearchedTicker(fullTicker.ticker, selectTickerUrl).then(function(res) {
    console.log('selectSearchedTicker promise returned');
    $rootScope.$emit("clear.tags.array");
    $rootScope.$emit("search.ticker.clicked", fullTicker);
});

最初看起来像是这样,给我带来了问题:

TickersSelectFactory.selectSearchedTicker(fullTicker.ticker, selectTickerUrl);
$rootScope.$emit("clear.tags.array");
$rootScope.$emit("search.ticker.clicked", fullTicker);

2 个答案:

答案 0 :(得分:3)

正确解决问题的方法是使用.then()提供的内置链接,并取消无关的$q.defer()对象:

switch (type) {
    case 'searched':
        return ApiFactory.getTickers(null, load).then(function(data) {
            searchedTickers.that = renderTickers(data.data.tickers, searchedTicker, 'searched');
            return searchedTickers.that;
        });
    ...
}

同样在你的第一个功能中:

function selectSearchedTicker(ticker, load) {
    return GetTickersFactory.getTickers('searched', load).then(function(data) {
        console.log('data',data);
        var tempTickers = GetTickersFactory.returnSearchedTickers();
        $rootScope.$emit("select.searched.ticker", tempTickers);
        return tempTickers;
    });
}

(注意函数开头的新return,确保此函数的调用者正确接收Promise

答案 1 :(得分:0)

想出来,我正在返回我的ApiFactory调用,结束了我的承诺链,之后我才能将数据添加到承诺中以便向上解决。

// return ApiFactory.getTickers(null, load).then(function(data) {
ApiFactory.getTickers(null, load).then(function(data) {
case 'searched':
    // With the return below, the code never got in to set the promise up and resolve it
    // return ApiFactory.getTickers(null, load).then(function(data) {
    ApiFactory.getTickers(null, load).then(function(data) {
        searchedTickers.that = renderTickers(data.data.tickers, searchedTicker, 'searched');
        promise = searchedTickers.that;
        console.log('searched promise',promise);
        deferred.resolve(promise);
    });
    break;