js 비동기 상태 모니터링

8122 단어
설명: 이 글 을 쓰 는 것 은 구설 에 오 르 기 를 바 라 는 것 이다.
배경
보고서 페이지 를 만 들 때 페이지 에 비동기 로 딩 이 많 고 디자인 된 loading 은 전체 적 이 며 한 페이지 에 하나씩 있 습 니 다.
loading 이 언제 나타 나 고 언제 사라 지 는 지 를 제어 합 니 다. 페이지 에 비동기 로 불 러 온 것 이 실행 되 었 는 지 실시 간 으로 알 아야 합 니 다. 모든 비동기 로 불 러 와 야 loading 이 멈 출 수 있 습 니 다.
또한, 사용자 가 페이지 를 조작 하면 한 부분 에서 불 러 오기 시작 합 니 다. loading 은 loading 효 과 를 실행 하 라 는 통 지 를 받 아야 합 니 다.
문제 의 난점 은 두 가지 가 있다.
1. 모든 비동기 가 불 러 오고 닫 힌 걸 어떻게 알았지?
2. 어떻게 loading 에 게 통지 합 니까?
사고
1. 아이디어 1
외부 상태 맵 을 설계 하고 비동기 실행 이 완료 되면 외부 변수의 값 을 수정 합 니 다.타 이 머 를 켜 면 이 맵 이 끊 이지 않 습 니 다. 모두 불 러 오 면 loading 을 중단 합 니 다.
//     
  var statusMap = {
      "  1": false,
      "  2": false
      // ...
  };
  
 //          
 setInterval(function () {
     //   statusMap
     if (isReady(statusMap)) {
         // show loading
     } else {
         // hide loading
     }
 }, 1000);
 
 //  
 $.ajax({
     //...
     success: function () {
         statusMap["  1"] = true;
     }
 });

 
이 방안 은 문 제 를 해결 할 수 있 지만 너무 우아 하지 않 아 요. 흐흐 흐................................................
2. 사고방식 2
promise 나 jQuery 의 deferred 를 사용 합 니 다.
$.when(  1,  2).done(function(){
    // show loading
}).fail(function(){
    // hide loading
});

 
이 방안 은 비동기 로드 가 완료 되면 promise 상 태 를 수정 할 수 없 기 때문에 이 장면 에 적합 하지 않다 는 단점 이 있다.
3. 사고방식 3
스스로 바퀴 를 만 드 는 것 은 사건 감청 을 바탕 으로 한 상태 가 바 뀌 면 모든 감청 대상 을 한 번 훑 어보 고 마지막 에 사용 상태 에 따라 대응 하 는 함 수 를 되 돌려 준다.
셋째, 사고방식 의 세 가지 실현
 
(function (win) {
    var watch = function () {
        var that = this;
        // arr
        if (arguments.length == 1 && Object.prototype.toString.call(arguments[0]) === "[object Array]") {
            that.watchArr = arguments[0];
        } else {
            that.watchArr = Array.prototype.slice.call(arguments);
        }
        that.watchArr.forEach(function (fairy) {
            fairy.watch = that;
        });
        that.isReady = true;
        return that;
    };
    watch.prototype = {
        ready: function (callback) {
            this.readyHandler = callback;
            this.check();
            return this;
        },
        unready: function (callback) {
            this.unReadyHandler = callback;
            this.check();
            return this;
        },
        add: function (fairy, check) {
            this.watchArr.push(fairy);
            if (check === undefined || check === true) {
                this.check();
            }
            return this;
        },
        check: function () {
            var nowIsReady = this.watchArr.every(function (fairy) {
                return fairy.isReady;
            });
            if (nowIsReady != this.isReady) {
                if (nowIsReady) {
                    if (this.readyHandler) {
                        this.readyHandler.call();
                        this.isReady = true;
                    }
                } else {
                    if (this.unReadyHandler) {
                        this.unReadyHandler.call();
                        this.isReady = false;
                    }
                }
            }
        },
        setIsReadyById: function (id, isReady, check) {
            var index = this.watchArr.indexOf(function (fairy) {
                fairy.id = id;
            });
            this.watchArr[index].isReady = isReady;
            if (check === undefined || check === true) {
                this.check();
            }
        },
        setIsReadyAll: function (isReady, check) {
            this.watchArr.forEach(function (fairy) {
                fairy.isReady = isReady;
            });
            if (check === undefined || check === true) {
                this.check();
            }
        }
    };

    var fairy = function (isReady) {
        this.id = new Date().getTime();
        this.isReady = isReady || false;
    };
    fairy.prototype = {
        toReady: function () {
            this.isReady = true;
            this.watch.check();
        },
        toUnReady: function () {
            this.isReady = false;
            this.watch.check();
        }
    };

    win.Watch = watch;
    win.Fairy = fairy;
})(window);

 
//   
var loader = new Loader();
var listFairy = new Fairy();
var chartFairy = new Fairy();
var watch = new Watch(listFairy, chartFairy);
watch.ready(function () {
    loader.stop();
}).unready(function () {
    loader.start();
});

//  
$.ajax({
    //...
    success: function () {
        listFairy.toReady();
    }
});

 
나 니 야, 약속 한 사건 은? 어디 갔 지?
그래, 구설 점 이 왔 다. 이 루어 지 는 과정 에서 사건 을 쓸 필요 가 없다 는 것 을 알 게 되 었 다.
마지막 까지 실현 하면 그것 이 사실은 변 형 된 사고 라 는 것 을 알 게 된다.
끝 이 아직 끝나 지 않 았 습 니 다. ...

좋은 웹페이지 즐겨찾기