nodejs 에서 Async 라 이브 러 리 소개

12498 단어
주소:https://github.com/caolan/async Async 의 내용 은 세 부분 으로 나 뉜 다.
  • 절차 통제: 10 가지 흔히 볼 수 있 는 절 차 를 간소화 하 는 처리
  • 집합 처리: 비동기 조작 처리 집합 중의 데이터
  • 를 어떻게 사용 합 니까?
  • 도구 류: 자주 사용 하 는 도구 류
  • 본 고 는 그 중에서 가장 간단 하고 자주 사용 하 는 절차 통제 부분 을 소개 한다.nodejs 는 비동기 프로 그래 밍 모델 이기 때문에 동기 프로 그래 밍 에서 쉽게 할 수 있 는 일 들 이 있 는데 지금 은 매우 번 거 로 워 졌 다.Async 의 프로 세 스 통 제 는 이러한 조작 을 간소화 하기 위 한 것 이다.
    series (tasks, [callback]) (여러 함수 가 순서대로 실행 되 고 데이터 교환 이 없습니다)
    여러 개의 비동기 함수 가 순서대로 호출 되 어야 하 며, 하 나 를 완성 한 후에 야 다음 을 실행 할 수 있 습 니 다.각 함수 간 에는 데이터 교환 이 없고 실행 순 서 를 확보 해 야 합 니 다.이 때 series 를 사용 할 수 있 습 니 다.순수 js 코드:
    step1(function(err, v1) {
            step2(function(err, v2) {
                    step3(function(err, v3) {
                            // do somethig with the err or values v1/v2/v3
                    }
            }
    });
    

    그 중에서 도 이 플러그 가 비교적 깊 은 것 을 볼 수 있 으 며, 몇 걸음 만 더 가면 더욱 깊 어 질 것 이다.코드 에서 모든 층 의 err 처 리 를 무시 합 니 다. 그렇지 않 으 면 if (err) return callback (err) 을 추가 하 기 를 기다 리 고 있 습 니 다. 그러면 더욱 번 거 롭 습 니 다.이러한 상황 에 대해 async 로 처리 합 니 다. 바로 다음 과 같 습 니 다.
    var async = require(‘async’) async.series([step1, step2, step3],
    function(err, values) {
            // do somethig with the err or values v1/v2/v3
    });
    

    코드 가 매우 간결 해 졌 고 모든 반전 의 오 류 를 자동 으로 처리 하 는 것 을 볼 수 있다.물론, 여기 서 가장 간단 한 예 만 보 여 줍 니 다. 실제 적 으로 우 리 는 모든 step 에서 일부 조작 을 수행 합 니 다. 이 때 는 다음 과 같이 쓸 수 있 습 니 다.
    var async = require(‘async’) async.series([function(cb) {
            step1(function(err, v1) {
                    // do something with v1
                    cb(err, v1);
            }),
            function(cb) {
                    step2(...)
            },
            function(cb) {
                    step3(...)
            }],
            function(err, values) {
                    // do somethig with the err or values v1/v2/v3
            });
    

    이 함수 의 상세 한 설명 은 함수 배열 의 모든 함 수 를 순서대로 실행 하고 모든 함수 가 실 행 된 후에 야 다음 함 수 를 실행 할 수 있 습 니 다.어떤 함수 가 리 셋 함수 에 error 를 전달 하면 뒤의 함수 가 실행 되 지 않 고 이 error 와 이미 실 행 된 함수 의 결 과 를 series 의 마지막 콜백 에 전달 합 니 다.모든 함수 가 실 행 된 후에 (오류 가 없 음) 모든 함수 가 리 셋 함수 에 전 달 된 결 과 를 하나의 배열 로 합 쳐 series 의 마지막 콜백 에 전 달 됩 니 다.제 이 슨 형식 으로 tasks 를 제공 할 수도 있다.모든 속성 은 함수 로 실행 되 고 결 과 는 json 형식 으로 series 의 마지막 콜백 에 전 달 됩 니 다.이런 방식 은 가 독성 이 좀 더 높다.구체 적 인 예 는 참고 할 수 있다.https://github.com/freewind/async_demo / blob / master / series. js 코드 에는 중간 에 어떤 함수 가 잘못 되면 series 함수 가 어떻게 처리 하 는 지, 만약 에 어떤 함수 가 리 턴 에 전 달 된 값 이 undefined, null, {}, [] 등 이 포함 되 어 있 습 니 다. series 는 어떻게 처리 하 는 지, 그리고 주의해 야 할 것 은 여러 series 호출 간 에 선후 가 없 기 때 문 입 니 다. series 자체 도 비동기 호출 이기 때 문 입 니 다.
    parallel (tasks, [callback]) (여러 함수 병행 실행)
    여러 함 수 를 병행 하여 실행 합 니 다. 모든 함 수 는 즉시 실 행 됩 니 다. 다른 함수 가 먼저 실 행 될 때 까지 기다 릴 필요 가 없습니다.최종 콜백 에 전 달 된 배열 의 데 이 터 는 완 료 된 순서 가 아 닌 tasks 에서 설명 한 순서 입 니 다.함수 가 잘못 되면 err 와 실 행 된 함수 의 결과 값 을 parallel 의 최종 callback 에 즉시 전달 합 니 다.실행 되 지 않 은 다른 함수 의 값 은 최종 데이터 로 전달 되 지 않 지만 위 치 를 차지 해 야 합 니 다.제 이 슨 형식의 tasks 를 지원 하 며 최종 콜 백 결과 도 제 이 슨 형식 이다.예제 코드:
    async.parallel([function(cb) {
            t.fire('a400', cb, 400)
    },
    function(cb) {
            t.fire('a200', cb, 200)
    },
    function(cb) {
            t.fire('a300', cb, 300)
    }],
    function(err, results) {
            log(’1 err: ‘, err); // -> undefined
            log(’1 results: ‘, results); // ->[ 'a400', 'a200', 'a300' ]
    });
    

    중간 에 오류 가 발생 한 예시:
    async.parallel([function(cb) {
            log('1: ', 'start');
            t.fire('a400', cb, 400)
    },
    //            callback,      
    function(cb) {
            log('2: ', 'start');
            t.err('e200', cb, 200)
    },
    function(cb) {
            log('3: ', 'start');
            t.fire('a100', cb, 100)
    }],
    function(err, results) {
            log(’2 err: ‘, err); // -> e200
            log(’2 results: ‘, results); // -> [ , undefined, 'a100' ]
    });
    

    json 형식 으로 tasks 전송
    async.parallel({
            a: function(cb) {
                    t.fire(‘a400′, cb, 400)
            },
            b: function(cb) {
                    t.fire(‘c300′, cb, 300)
            }
    },
    function(err, results) {
            log(’3 err: ‘, err); // -> undefined
            log(’3 results: ‘, results); // -> { b: ‘c300′, a: ‘a400′ }
    });
    

    더 자세 한 예제 참조:https://github.com/freewind/async_demo/blob/master/parallel.js
    waterfall (tasks, [callback]) (여러 함수 가 순서대로 실행 되 고 앞의 출력 은 뒤의 입력 입 니 다)
    seires 와 비슷 하여 순서대로 여러 함 수 를 실행 합 니 다.다른 점 에서 모든 함수 가 발생 하 는 값 은 다음 함수 에 전 달 됩 니 다.중간 에 오류 가 발생 하면 뒤의 함 수 는 실행 되 지 않 습 니 다.오류 메시지 및 이전에 발생 한 결 과 는 워 터 폴 의 최종 콜 백 에 전 달 됩 니 다.이 함 수 는 워 터 폴 (폭포) 이 라 고 하 는데 폭포 가 위 에서 아래로 중간 에 돌출 된 돌 을 뚫 고 지나 가 는 것 을 상상 할 수 있 습 니 다.이 함 수 는 json 형식의 tasks 를 지원 하지 않 습 니 다.
    async.waterfall([function(cb) {
            log('1: ', 'start');
            cb(null, 3);
    },
    function(n, cb) {
            log('2: ', n);
            t.inc(n, cb);
    },
    function(n, cb) {
            log('3: ', n);
            t.fire(n * n, cb);
    }],
    function(err, result) {
            log(’1 err: ‘, err); // -> null
            log(’1 result: ‘, result); // -> 16
    });
    

    더 자세 한 예제 참조:https://github.com/freewind/async_demo/blob/master/waterfall.js
    auto (tasks, [callback]) (여러 함수 가 의존 관계 가 있 고 병행 실행 이 있 으 며 순서대로 실행 되 는 경우 도 있 습 니 다)
    의존 관계 가 있 는 여러 임무 의 집행 을 처리 하 는 데 쓰 인 다.예 를 들 어 어떤 임 무 는 서로 독립 되 어 병행 할 수 있다.그러나 어떤 임 무 는 다른 어떤 임무 에 의존 하고 그 임무 가 완 성 된 후에 야 수행 할 수 있다.비록 우 리 는 async. parallel 과 async. series 를 결합 하여 이 기능 을 실현 할 수 있 지만, 작업 간 의 관계 가 복잡 하면 코드 가 상당히 복잡 할 것 이 며, 이후 에 새로운 임 무 를 추가 하려 면 매우 번 거 로 울 것 이다.이때 async. auto 를 사용 하면 적은 노력 으로 큰 효 과 를 거 둘 수 있 습 니 다.작업 중간 에 오류 가 발생 하면 이 오 류 를 최종 콜백 에 전송 합 니 다. 모든 작업 (실 행 된 것 포함) 에서 발생 하 는 데 이 터 는 무 시 됩 니 다.여기 서 내 가 프로그램 을 쓰 려 고 한다 고 가정 하면 다음 과 같은 몇 가지 일 을 완성 해 야 한다. 어 딘 가 에서 데 이 터 를 얻어 하 드 디스크 에 새로운 디 렉 터 리 를 만들어 디 렉 터 리 아래 의 한 파일 에 데 이 터 를 기록 하여 메 일 을 보 내 고 파일 을 첨부 파일 로 다른 사람 에 게 보 내야 한다.이 임 무 를 분석 하면 1 과 2 를 병행 할 수 있 고 3 은 1 과 2 를 기 다 려 야 하 며 4 는 3 을 기 다 려 야 한 다 는 것 을 알 수 있다.
    async.auto({
            getData: function(callback) {
                    setTimeout(function() {
                            console.log(’1 : got data’);
                            callback();
                    },
                    300);
            },
            makeFolder: function(callback) {
                    setTimeout(function() {
                            console.log(’1 : made folder’);
                            callback();
                    },
                    200);
            },
            writeFile: ['getData', 'makeFolder',
            function(callback) {
                    setTimeout(function() {
                            console.log('1: wrote file');
                            callback(null, 'myfile');
                    },
                    300);
            }],
            emailFiles: ['writeFile',
            function(callback, results) {
                    log('1: emailed file: ', results.writeFile); // -> myfile
                    callback(null, results.writeFile);
            }]
    },
    function(err, results) {
            log(’1 : err: ‘, err); // -> null
            log(’1 : results: ‘, results); // -> { makeFolder: undefined,
            // getData: undefined,
            // writeFile: ‘myfile’,
            // emailFiles: ‘myfile’ }
    });
    

    더 자세 한 예제 참조:https://github.com/freewind/async_demo/blob/master/auto.js
    whilst (test, fn, callback) (비동기 호출 가능 한 while)
    while 에 해당 하지만 이 중 비동기 호출 은 완 료 된 후에 야 다음 순환 을 진행 할 수 있 습 니 다.예 를 들 면 다음 과 같다.
    var count1 = 0;
    async.whilst(function() {
            return count1 < 3
    },
    function(cb) {
            log(’1 count: ‘, count1);
            count1++;
            setTimeout(cb, 1000);
    },
    function(err) {
            // 3s have passed
            log(’1 err: ‘, err); // -> undefined
    });
    

    그것 은 다음 과 같다.
    try {
        whilst(test) {
            fn();
        }
        callback();
    } catch(err) {
        callback(err);
    }
    

    이 함수 의 기능 은 비교적 간단 하 며, 조건 변 수 는 일반적으로 밖 에 정의 되 어 있 으 며, 모든 함수 에 접근 할 수 있 습 니 다.순환 중, 비동기 호출 시 발생 하 는 값 은 실제로 버 려 졌 습 니 다. 마지막 으로 그 콜백 은 잘못된 정보 만 들 어 올 수 있 기 때 문 입 니 다.또한, 두 번 째 함수 fn 은 함수 cb 를 받 아들 일 수 있어 야 합 니 다. 이 cb 는 최종 적 으로 실행 되 어야 합 니 다. 오류 나 정상 적 인 끝 을 표시 하 는 데 사 용 됩 니 다.더 자세 한 예제 참조:https://github.com/freewind/async_demo/blob/master/whilst_until.js
    until (test, fn, callback) (while 와 비슷 하지만 판단 조건 은 반대)
     var count4 = 0;
     async.until(function() {
         return count4 > 3
     },
     function(cb) {
         log(’4 count: ‘, count4);
         count4++;
         setTimeout(cb, 200);
     },
     function(err) {
         // 4s have passed
         log(’4 err: ‘, err); // -> undefined
     });
    

    첫 번 째 함수 조건 이 false 일 때 두 번 째 함 수 를 계속 실행 합 니 다. 그렇지 않 으 면 튀 어 나 옵 니 다.
    queue (Worker 수 를 설정 할 수 있 는 대기 열)
    quue 는 강화 판 parallel 에 해당 하 며, 주로 워 커 의 수량 을 제한 하여 한꺼번에 실행 하지 않 습 니 다.워 커 의 수가 부족 할 때, 새로 추 가 된 작업 은 새로운 워 커 가 사용 할 수 있 을 때 까지 줄 을 서서 기다 릴 것 입 니 다.이 함 수 는 워 커 가 다 썼 을 때, 작업 을 기다 리 지 않 았 을 때, 모두 실 행 했 을 때 등 여러 가지 점 이 있 습 니 다.하나의 queue 를 정의 합 니 다. 워 커 의 수 는 2 이 며, 작업 을 수행 할 때 로 그 를 기록 합 니 다:
    var q = async.queue(function(task, callback) {
        log(‘worker is processing task: ‘, task.name);
        task.run(callback);
    }, 2);
    

    worker 수량 이 다 떨 어 질 때 saturated 함 수 를 호출 합 니 다:
       q.saturated = function() {
           log(‘all workers to be used’);
       }
    

    마지막 작업 을 워 커 에 게 맡 길 때 empty 함 수 를 호출 합 니 다.
       q.empty = function() {
           log(‘no more tasks wating’);
       }
    

    모든 작업 이 완료 되면 drain 함 수 를 호출 합 니 다.
       q.drain = function() {
           console.log(‘all tasks have been processed’);
       }
    

    여러 퀘 스 트 를 넣 으 면 한 번 에 하나 넣 거나 한 번 에 여러 개 넣 을 수 있 습 니 다.
    q.push({
            name: ’t1′,
            run: function(cb) {
                    log(‘t1 is running, waiting tasks: ‘, q.length());
                    t.fire(‘t1′, cb, 400); // 400ms   
            }
    },
    function(err) {
            log(‘t1 executed’);
    });
    
    q.push([{
            name: 't3',
            run: function(cb) {
                    log('t3 is running, waiting tasks: ', q.length());
                    t.fire('t3', cb, 300); // 300ms   
            }
    },
    {
            name: 't4',
            run: function(cb) {
                    log('t4 is running, waiting tasks: ', q.length());
                    t.fire('t4', cb, 500); // 500ms   
            }
    }],
    function(err) {
            log(‘t3 / 4 executed’);
    });
    

    더 자세 한 예제 참조:https://github.com/freewind/async_demo/blob/master/queue.js
    iterator (tasks) (몇 개의 함 수 를 iterator 로 포장)
    한 그룹의 함 수 를 하나의 iterator 로 포장 하면 next () 를 통 해 다음 함 수 를 기점 으로 하 는 새로운 iterator 를 얻 을 수 있 습 니 다.이 함 수 는 보통 async 가 내부 에서 사용 하지만 필요 할 때 우리 코드 에서 도 사용 할 수 있 습 니 다.
    var iter = async.iterator([function() {
            console.log('111')
    },
    function() {
            console.log('222')
    },
    function() {
            console.log('333')
    }]);
    console.log(iter());
    console.log(iter.next());
    

    직접 호출 () 하면 현재 함 수 를 실행 하고 다음 함 수 를 기점 으로 하 는 새로운 iterator 를 되 돌려 줍 니 다.next () 를 호출 하면 현재 함 수 를 실행 하지 않 고 다음 함 수 를 시작 으로 하 는 새 iterator 를 되 돌려 줍 니 다.같은 iterator 에 대해 서 는 next () 를 여러 번 호출 하여 자신 에 게 영향 을 주지 않 습 니 다.하나의 요소 만 남 으 면 next () 를 호출 하면 null 로 돌아 갑 니 다.더 자세 한 예제 참조:https://github.com/freewind/async_demo/blob/master/iterator.js
    apply (function, arguments..) (함수 에 미리 바 인 딩 된 매개 변수)
    apply 는 매우 좋 은 함수 입 니 다. 함수 에 여러 개의 인 자 를 미리 연결 하고 직접 호출 할 수 있 는 새로운 함 수 를 생 성하 여 코드 를 간소화 할 수 있 습 니 다.함수:
       function(callback) { t.inc(3, callback); }
    

    apply 로 다음 과 같이 바 꿀 수 있 습 니 다.
       async.apply(t.inc, 3);
    

    또한 일부 함수 에 값 을 미리 설정 하여 새로운 함 수 를 얻 을 수 있 습 니 다:
       var log = async.apply(console.log, ">");
       log(‘hello’);
       // > hello
    

    더 자세 한 코드 참조:https://github.com/freewind/async_demo/blob/master/apply.js
    nextTick (callback) (nodejs 와 브 라 우 저 양쪽 행동 일치)
    nextTick 의 역할 은 nodejs 의 nextTick 과 마찬가지 로 특정한 함 수 를 대기 열의 끝 에 호출 합 니 다.그러나 브 라 우 저 에 서 는 setTimeout (callback, 0) 만 사용 할 수 있 지만, 이 방법 은 때때로 다른 높 은 우선 순위 의 작업 을 앞으로 삽입 할 수 있 습 니 다.그래서 이 nextTick 을 제공 하여 같은 코드 가 서버 쪽 과 브 라 우 저 쪽 에서 일치 하도록 합 니 다.
    var calls = [];
    async.nextTick(function() {
            calls.push(‘two’);
    });
    calls.push(‘one’);
    async.nextTick(function() {
            console.log(calls); // -> [ 'one', 'two' ]
    });
    

    더 자세 한 코드 참조:https://github.com/freewind/async_demo/blob/master/nextTick.js

    좋은 웹페이지 즐겨찾기