iT邦幫忙

0

使用Angularjs $http 非同步問題

  • 分享至 

  • xImage

各位好, 使用$http時遇到問題, 以下程式碼為:
先透過post取得user list, 再根據個數以for loop送get取得user info

  1. 目前已知這會有非同步問題, 但不曉得該如何改寫。
  2. 為何userinfo會有資料, 但userinfo[0]是undefined?
MyApp.controller('MyCtrl', function($scope, $http) {
    $scope.UM_FuncSearch = function() {
        $http.post("test", data)
        .then(function(rsp) {
            var length = rsp.data.user_list.length;
            var userlist = rsp.data.user_list;
            var userinfo = [];
            if(length != 0){
                for(var i = 0; i < length; i++){
                    var url = "test?uniqname=" + userlist[i].uniqname;
                    $http.get(url)
                    .then(function(rsp) {
                        var obj = rsp.data.user_info;
                        userinfo.push(obj);
                    });
                }
                console.log(userinfo);
                console.log(userinfo[0]);
            }
        });
    }
});

Edit:
有找到程式碼, 改寫後似乎可以, 但不太懂...:

MyApp.controller('MyCtrl', function($scope, $http, $q) {
    $scope.UM_FuncSearch = function() {
        $http.post("test", data)
        .then(function(rsp) {
            var length = rsp.data.user_list.length;
            var userlist = rsp.data.user_list;
            var userinfo = [];
            if(length != 0){
                for(var i = 0; i < length; i++){
                    var url = "test?uniqname=" + userlist[i].uniqname;
                    userinfo.push(test(url));
                }
                console.log(userinfo);
                console.log(userinfo[0]);
            }
        });
    }
    function test(url){
        var deferred = $q.defer();
        var promise = deferred.promise;
        $http.get(url)
        .then(function(rsp) {
            deferred.resolve(rsp.data.user_info); 
        });
        return promise;
    }
});
ccutmis iT邦高手 2 級 ‧ 2019-10-04 18:04:40 檢舉
Q:為何userinfo會有資料, 但userinfo[0]是undefined?
A: 有些物件用[0]去取值的結果就是undefined,例如: number或object,你可以用typeof(userinfo)檢查看看這是什麼物件,再依物件特性去取值
樓上不要誤人子弟,那是非同步的資料!本來就還沒得到值,所以才會是undefined。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
dragonH
iT邦超人 5 級 ‧ 2019-10-04 19:24:07
最佳解答

沒寫過 angular

不過這是官網 $q 的說明

The streamlined ES6 style promise is essentially just using $q as a constructor which takes a resolver function as the first argument. This is similar to the native Promise implementation from ES6

簡單來說它就是一個包裝了 promise 的東西

也是你的情況所需要的

這是我寫的範例

codepen

1 .

目前已知這會有非同步問題, 但不曉得該如何改寫。

2 .

為何userinfo會有資料, 但userinfo[0]是undefined?

推測是 當執行到

console.log(userinfo[0]);

promise 還沒拿到結果

看更多先前的回應...收起先前的回應...
ccutmis iT邦高手 2 級 ‧ 2019-10-04 20:14:17 檢舉

promise 還沒拿到結果

他的 console.log(userinfo[0]); 是包在 .then(){...}裡面喔,
promise執行正常的話就是接著執行.then()裡面的東西對吧,
所以會有他說的 印userinfo有內容(表示有成功抓到東西),
但印userinfo[0]結果是undefined,
這個表示內容不是字串或陣列,是什麼只有樓主知道...
因為他沒說console.log(userinfo)印出來的是什麼東東。

dragonH iT邦超人 5 級 ‧ 2019-10-04 20:22:51 檢舉

可是他在第一層的 then()裡面

還有一個迴圈

迴圈裡面看起來會回傳好幾個 promise

userinfo 的值 應該是在這決定的

但印userinfo[0]結果是undefined,

這個應該是因為他在前面有先宣告

var userinfo = [];

ccutmis iT邦高手 2 級 ‧ 2019-10-04 21:10:39 檢舉

陣列內容如果是空的,userinfo[0]會是undefined,
但是因為樓主說
console.log(userinfo); //有陣列內容
console.log(userinfo[0]); //傳回undefined
這個就很奇怪,大概他是二件事混在一起講了

dragonH iT邦超人 5 級 ‧ 2019-10-04 21:34:22 檢舉

/images/emoticon/emoticon82.gif

阿薩姆 iT邦新手 4 級 ‧ 2019-10-07 09:13:46 檢舉

兩位好!
可能是我沒敘述清楚讓兩位誤會了, "為何userinfo會有資料, 但userinfo[0]是undefined?" 指的是第一段程式碼, 並沒有使用promise, 第二段程式碼改用promise之後有拿到內容了, 但還不太懂原理。

dragonH iT邦超人 5 級 ‧ 2019-10-07 09:16:11 檢舉

wcliao_public

這樣的話

我會建議先了解一般的 promise

再去了解 angular $q 的用法

阿薩姆 iT邦新手 4 級 ‧ 2019-10-07 09:19:55 檢舉

好的!另外想請教, 若沒有使用Angularjs, 我這個需求通常如何實作?
需求:先用url1拿到成員名單, 使用url2跑迴圈拿到各成員詳細資料
也是採用類似promise的方式嗎?

dragonH iT邦超人 5 級 ‧ 2019-10-07 09:28:17 檢舉

wcliao_public

只要你有非同步的需求

通常都會用 promise 或者 callback

例如

http request 要完資料後更新畫面

用跟 a 資料庫要到的資料去跟 b 資料庫要資料

或者

你後面要執行的 code

要前面執行過後才執行

都可以用

阿薩姆 iT邦新手 4 級 ‧ 2019-10-07 09:33:19 檢舉

好的! 我研究看看!

dragonH iT邦超人 5 級 ‧ 2019-10-07 09:46:05 檢舉

codepen

這給你參考

http request 拿到 圖片 url

然後更新 圖片

你可以試試如果不用 promise 會發生什麼事

userinfo.push(test(url));
test執行promise的函式,當你想要讀取該值就必須等它執行完成再往下做
可以考慮使用async的機制去確保取得資料

我要發表回答

立即登入回答