Programing

ES6 약속이 있으므로 Q 또는 BlueBird와 같은 약속 라이브러리를 사용해야 할 이유가 있습니까?

lottogame 2020. 4. 26. 20:59
반응형

ES6 약속이 있으므로 Q 또는 BlueBird와 같은 약속 라이브러리를 사용해야 할 이유가 있습니까? [닫은]


Node.js가 약속에 대한 기본 지원을 추가 한 후에도 Q 또는 BlueBird와 같은 라이브러리를 사용해야하는 이유가 있습니까?

예를 들어, 새 프로젝트를 시작하고이 프로젝트에서 이러한 라이브러리를 사용하는 종속성이 없다고 가정하면 해당 라이브러리를 사용할 이유가 더 이상 없다고 말할 수 있습니까?


구식 속임수는 직업에 맞는 도구를 선택해야한다는 것입니다. ES6 약속은 기본을 제공합니다. 당신이 원하거나 필요로하는 모든 것이 기본이라면, 그것은 당신에게 잘 작동 할 것입니다. 그러나 도구 상자에는 기본 사항보다 더 많은 도구가 있으며 이러한 추가 도구가 매우 유용한 상황이 있습니다. 그리고 ES6 약속에는 거의 모든 node.js 프로젝트에 유용한 약속과 같은 몇 가지 기본 사항이 누락되어 있다고 주장합니다.

저는 Bluebird promise 라이브러리에 가장 익숙 하므로 대부분 해당 라이브러리에 대한 경험을 통해 이야기하겠습니다.

보다 유능한 Promise 라이브러리를 사용해야하는 6 가지 이유는 다음과 같습니다.

  1. 인터페이스 비동기 비 Promisified - .promisify()그리고 .promisifyAll()한 줄의 코드는 전체 인터페이스의 promisified 버전을 생성 - 여전히 일반 콜백을 필요로하고 아직 약속을 반환하지 않는 모든 비동기 인터페이스를 처리 할 수 매우 유용합니다.

  2. 빠름 -Bluebird는 대부분의 환경에서 기본 약속보다 훨씬 빠릅니다 .

  3. 비동기 배열 반복 시퀀싱 - Promise.mapSeries()또는 Promise.reduce()각 요소에 대해 비동기 작업을 호출하는 동시에 배열을 반복 할 수 있지만 비동기 작업을 시퀀싱하여 동시에 수행되는 것은 아닙니다. 대상 서버에 필요하거나 하나의 결과를 다음 서버로 전달해야하기 때문에이 작업을 수행 할 수 있습니다.

  4. Polyfill- 구 버전의 브라우저 클라이언트에서 약속을 사용하려면 어쨌든 polyfill이 필요합니다. 유능한 폴리 필을 얻을 수도 있습니다. node.js에는 ES6 약속이 있으므로 node.js에는 폴리 필이 필요하지 않지만 브라우저에는있을 수 있습니다. node.js 서버와 클라이언트를 모두 코딩하는 경우 동일한 약속 라이브러리와 기능을 둘 다 (코드 공유, 환경 간 컨텍스트 전환, 비동기 코드에 공통 코딩 기술 사용 등)에 매우 유용 할 수 있습니다. ).

  5. 기타 유용한 기능 - 파랑새는있다 Promise.map(), Promise.some(), Promise.any(), Promise.filter(), Promise.each()Promise.props()모든 때때로 편리합니다. 이러한 작업은 ES6 약속 및 추가 코드를 사용하여 수행 할 수 있지만 Bluebird는 이러한 작업이 이미 사전 빌드 및 사전 테스트되었으므로이를 사용하는 것이 더 간단하고 적은 코드입니다.

  6. 기본 제공 경고 및 전체 스택 추적 -Bluebird에는 잘못된 코드 또는 버그 일 수있는 문제를 경고하는 여러 가지 기본 제공 경고가 있습니다. 예를 들어, .then()해당 약속을 현재 약속 체인에 연결하지 않고 처리기 내에 새로운 약속을 만드는 함수를 호출하면 대부분의 경우 우발적 인 버그이며 Bluebird는 경고를 표시합니다. 효과. 다른 내장 블루 버드 경고는 여기설명되어 있습니다 .

이러한 다양한 주제에 대한 자세한 내용은 다음과 같습니다.

약속하다

모든 node.js 프로젝트에서 .promisifyAll()모듈과 같은 표준 node.js 모듈을 많이 사용하기 때문에 모든 곳에서 Bluebird를 즉시 사용 fs합니다.

Node.js 자체는 fs모듈 과 같은 비동기 IO를 수행하는 내장 모듈에 대한 약속 인터페이스를 제공하지 않습니다 . 따라서 해당 인터페이스와 함께 약속을 사용하려면 사용하는 각 모듈 함수 주위에 약속 래퍼를 직접 코딩하거나 약속을 사용하지 않거나 사용할 수있는 라이브러리를 가져와야합니다.

블루 버드의 Promise.promisify()Promise.promisifyAll()약속을 반환 컨벤션 비동기 API를 호출 Node.js를의 자동 포장을 제공한다. 매우 유용하고 시간을 절약 할 수 있습니다. 나는 항상 그것을 사용합니다.

작동 방식의 예는 다음과 같습니다.

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.readFileAsync('somefile.text').then(function(data) {
   // do something with data here
});

대안은 fs사용하려는 API 에 대해 자체 약속 래퍼를 수동으로 만드는 것입니다 .

const fs = require('fs');

function readFileAsync(file, options) {
    return new Promise(function(resolve, reject) {
        fs.readFile(file, options, function(err, data) {
            if (err) {
                reject(err);
            } else {
                 resolve(data);
            }
        });
    });
}

readFileAsync('somefile.text').then(function(data) {
   // do something with data here
});

또한 사용하려는 각 API 함수에 대해 수동으로이 작업을 수행해야합니다. 이것은 분명히 이해가되지 않습니다. 상용구 코드입니다. 이 작업을 수행하는 유틸리티를 얻을 수도 있습니다. 블루 버드 Promise.promisify()Promise.promisifyAll()같은 유틸리티입니다.

다른 유용한 기능

다음은 특히 유용한 Bluebird 기능 중 일부입니다 (코드를 저장하거나 개발 속도를 높이는 방법에 대한 몇 가지 코드 예제가 있음).

Promise.promisify()
Promise.promisifyAll()
Promise.map()
Promise.reduce()
Promise.mapSeries()
Promise.delay()

유용한 기능 외에도 Promise.map()동시에 실행할 수있는 작업 수를 지정할 수있는 동시성 옵션도 지원 합니다.이 기능 은 할 일이 많을 때 특히 유용하지만 외부를 압도 할 수없는 경우에 특히 유용합니다. 자원.

이들 중 일부는 독립형이라고 할 수 있으며 많은 코드를 절약 할 수있는 iterable로 해결된다는 약속에 사용될 수 있습니다.


폴리 필

브라우저 프로젝트에서는 일반적으로 Promise를 지원하지 않는 일부 브라우저를 계속 지원하고자하므로 결국에는 폴리 필이 필요합니다. jQuery를 사용하는 경우 jQuery에 내장 된 약속 지원을 사용할 수도 있습니다 (jQuery 3.0에서 수정 된 방식으로 고통 스럽지만 비표준 임에도 불구하고).하지만 프로젝트에 중요한 비동기 활동이 포함되어 있다면 블루 버드의 확장 기능은 매우 유용합니다.


더 빠른

또한 Bluebird의 약속은 V8에 제공된 약속보다 훨씬 빠르다는 점에 주목할 가치가 있습니다. 해당 주제에 대한 자세한 내용은 이 게시물참조하십시오 .


큰 일 Node.js가 누락되었습니다

node.js 개발에서 Bluebird를 덜 사용하는 것을 고려하게 만드는 것은 node.js가 약속 함수에 내장되어 있으면 다음과 같이 할 수 있습니다.

const fs = requirep('fs');

fs.readFileAsync('somefile.text').then(function(data) {
   // do something with data here
});

또는 내장 모듈의 일부로 이미 약속 된 방법을 제공하십시오.

그때까지, 나는 이것을 Bluebird와 함께합니다 :

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.readFileAsync('somefile.text').then(function(data) {
   // do something with data here
});

ES6 promise 지원이 node.js에 내장되어 있고 내장 모듈 중 어느 것도 약속을 반환하지 않는 것이 약간 이상합니다. 이것은 node.js에서 정렬해야합니다. 그때까지 나는 Bluebird를 사용하여 전체 라이브러리를 약속합니다. 따라서 내장 모듈 중 어느 것도 먼저 약속을 수동으로 감싸지 않고 약속을 사용할 수 없으므로 node.js에서 약속이 약 20 % 구현 된 것처럼 느낍니다.


다음은 일반 약속과 블루 버드의 약속과 Promise.map()파일 세트를 동시에 읽고 모든 데이터를 다룰 때 알리는 예입니다.

일반 약속

const files = ["file1.txt", "fileA.txt", "fileB.txt"];
const fs = require('fs');

// make promise version of fs.readFile()
function fsReadFileP(file, options) {
    return new Promise(function(resolve, reject) {
        fs.readFile(file, options, function(err, data) {
            if (err) return reject(err);
            resolve(data);
        });
    });
}


Promise.all(files.map(fsReadFileP)).then(function(results) {
    // files data in results Array
}, function(err) {
    // error here
});

블루 버드 Promise.map()Promise.promisifyAll()

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
const files = ["file1.txt", "fileA.txt", "fileB.txt"];

Promise.map(files, fs.readFileAsync).then(function(results) {
    // files data in results Array
}, function(err) {
    // error here
});

다음은 일반 약속과 블루 버드의 약속의 예이며 Promise.map()원격 호스트에서 한 번에 최대 4 개까지 읽을 수 있지만 허용되는 한 많은 요청을 병렬로 유지하려는 URL을 읽을 때 다음과 같습니다.

평범한 JS 약속

const request = require('request');
const urls = [url1, url2, url3, url4, url5, ....];

// make promisified version of request.get()
function requestGetP(url) {
    return new Promise(function(resolve, reject) {
        request.get(url, function(err, data) {
            if (err) return reject(err);
            resolve(data);
        });
    });
}

function getURLs(urlArray, concurrentLimit) {
    var numInFlight = 0;
    var index = 0;
    var results = new Array(urlArray.length);
    return new Promise(function(resolve, reject) {
        function next() {
            // load more until concurrentLimit is reached or until we got to the last one
            while (numInFlight < concurrentLimit && index < urlArray.length) {
                (function(i) {
                    requestGetP(urlArray[index++]).then(function(data) {
                        --numInFlight;
                        results[i] = data;
                        next();
                    }, function(err) {
                        reject(err);
                    });
                    ++numInFlight;
                })(index);
            }
            // since we always call next() upon completion of a request, we can test here
            // to see if there was nothing left to do or finish
            if (numInFlight === 0 && index === urlArray.length) {
                resolve(results);
            }
        }
        next();
    });
}

블루 버드 약속

const Promise = require('bluebird');
const request = Promise.promisifyAll(require('request'));
const urls = [url1, url2, url3, url4, url5, ....];

Promise.map(urls, request.getAsync, {concurrency: 4}).then(function(results) {
    // urls fetched in order in results Array
}, function(err) {
    // error here
});

참고 : https://stackoverflow.com/questions/34960886/are-there-still-reasons-to-use-promise-libraries-like-q-or-bluebird-now-that-we

반응형