웹 프론트엔드 JS 튜토리얼 JavaScript 비동기 프로그래밍의 Promise 패턴 샘플 코드에 대한 자세한 소개

JavaScript 비동기 프로그래밍의 Promise 패턴 샘플 코드에 대한 자세한 소개

Mar 11, 2017 pm 03:19 PM

비동기 모드는 웹 프로그래밍에서 점점 더 중요해지고 있습니다. 주류 웹 언어인 Javascript의 경우 이 모드는 구현하기가 그리 쉽지 않습니다. 이러한 이유로 많은 Javascript 라이브러리(예: jQuery 및 Dojo)에서는 소위 말하는 모드를 추가합니다. 이는 약속의 추상화입니다(때때로 지연이라고도 함). 이러한 라이브러리를 통해 개발자는 실제 프로그래밍에서 Promise 패턴을 사용할 수 있습니다. IE 공식 블로그는 최근 XMLHttpRequest2를 사용하여 약속 모드를 실행하는 방법을 자세히 설명하는 기사를 게시했습니다. 관련 개념과 적용 사례를 살펴보겠습니다.

웹 페이지에 비동기 작업(XMLHttpRequest2 또는 Web Workers를 통해)이 있는 예를 생각해 보세요. Web 2.0 기술이 심화됨에 따라 브라우저 측에서는 점점 더 많은 컴퓨팅 압력을 받고 있으므로 "동시성"은 긍정적인 의미를 갖습니다. 개발자의 경우 페이지와 사용자 간의 상호 작용을 영향 없이 유지해야 할 뿐만 아니라 페이지와 비동기 작업 간의 관계를 조정해야 합니다. 이러한 종류의 비선형 실행 프로그래밍 요구 사항은 적응하기 어렵습니다. 페이지 상호 작용을 제쳐두고 비동기 호출을 위해 처리해야 하는 두 가지 결과, 즉 성공적인 작업과 실패 처리를 생각해 볼 수 있습니다. 호출이 성공한 후 다른 Ajax 요청에서 반환된 결과를 사용해야 할 수도 있습니다. 그러면 "함수 체인" 상황이 발생합니다(저자의 다른 기사 "NodeJS의 비동기 프로그래밍 스타일" 설명에 자세히 설명되어 있음). 이러한 상황은 프로그래밍을 복잡하게 만듭니다. 다음 코드 예제를 살펴보십시오(XMLHttpRequest2 기반):

function searchTwitter(term, onload, onerror) {

     var xhr, results, url;
     url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;
     xhr = new XMLHttpRequest();
     xhr.open('GET', url, true);

     xhr.onload = function (e) {
         if (this.status === 200) {
             results = JSON.parse(this.responseText);
             onload(results);
         }
     };

     xhr.onerror = function (e) {
         onerror(e);
     };

     xhr.send();
 }

 function handleError(error) {
     /* handle the error */
 }

 function concatResults() {
     /* order tweets by date */
 }

 function loadTweets() {
     var container = document.getElementById('container');

     searchTwitter('#IE10', function (data1) {
         searchTwitter('#IE9', function (data2) {
             /* Reshuffle due to date */
             var totalResults = concatResults(data1.results, data2.results);
             totalResults.forEach(function (tweet) {
                 var el = document.createElement('li');
                 el.innerText = tweet.text;
                 container.appendChild(el);
             });
         }, handleError);
     }, handleError);
 }
로그인 후 복사

위 코드의 기능은 해시태그 IE10 및 IE9가 포함된 Twitter 콘텐츠를 가져와서 페이지에 표시하는 것입니다. 이런 종류의 중첩된 콜백 함수는 이해하기 어렵습니다. 개발자는 어떤 코드가 애플리케이션의 비즈니스 로직에 사용되는지, 어떤 코드가 비동기 함수 호출을 처리하는지 주의 깊게 분석해야 합니다. 오류 처리도 분해되어 다양한 곳에서 오류 발생을 감지하고 그에 따라 처리해야 합니다.

비동기 프로그래밍의 복잡성을 줄이기 위해 개발자들은 비동기 작업을 처리하는 쉬운 방법을 찾고 있었습니다. 이러한 처리 패턴 중 하나를 약속(promise)이라고 하며, 이는 장기간 실행될 수 있고 반드시 완료될 필요는 없는 작업의 결과를 나타냅니다. 이 패턴은 긴 작업이 완료될 때까지 차단하고 기다리는 대신 약속된 결과를 나타내는 개체를 반환합니다.

페이지 코드가 타사 API에 액세스해야 하는 경우를 생각해 보세요. 네트워크 지연으로 인해 응답 시간이 길어질 수 있습니다. 이 경우 비동기 프로그래밍을 사용하면 전체 페이지와 사용자 간의 상호 작용에 영향을 미치지 않습니다. Promise 모드는 일반적으로 상태가 변경될 때 해당 콜백 함수를 등록하기 위해 then 호출되는 메서드를 구현합니다. 예를 들어, 다음 코드 예는 다음과 같습니다.

searchTwitter(term).then(filterResults).then(displayResults);
로그인 후 복사

프로미스 모드는 언제든지 이행되지 않음, 해결됨, 거부됨의 세 가지 상태 중 하나입니다. CommonJS Promise/A 표준을 예로 들면, Promise 객체의 then 메소드는 완료 및 거부된 상태에 대한 처리 기능을 추가하는 역할을 합니다. then 메소드는 Promise 파이프라인의 형성을 용이하게 하기 위해 또 다른 Promise 객체를 반환합니다. Promise 객체를 반환하는 이 메소드는 개발자가 then(resolvedHandler, RejectedHandler);와 같은 비동기 작업을 연결하도록 지원할 수 있습니다. ResolvedHandler 콜백 함수는 Promise 객체가 완료 상태에 진입하고 결과를 전달할 때 트리거됩니다. RejectedHandler 함수는 거부 상태에서 호출됩니다.

Promise 패턴을 사용하면 위의 Twitter 예제를 다시 구현할 수 있습니다. 구현 방법을 더 잘 이해하기 위해 처음부터 Promise 패턴 프레임워크를 구축하려고 했습니다. 먼저 약속을 저장할 객체가 필요합니다.

var Promise = function () {
        /* initialize promise */
    };
로그인 후 복사

다음으로 완료 및 거부 상태를 처리하기 위해 두 개의 매개 변수를 받는 then 메서드를 정의합니다.

Promise.prototype.then = function (onResolved, onRejected) {
     /* invoke handlers based upon state transition */
 };
로그인 후 복사

동시에 미완료에서 완료로, 미완료에서 거부로 상태 전환을 실행하려면 두 가지 방법이 필요합니다.

Promise.prototype.resolve = function (value) {
     /* move from unfulfilled to resolved */
 };

 Promise.prototype.reject = function (error) {
     /* move from unfulfilled to rejected */
 };
로그인 후 복사

이제 Promise Shelf가 구축되었으므로 IE10의 콘텐츠만 가져온다고 가정하고 위의 예를 계속 진행할 수 있습니다. Ajax 요청을 보내고 이를 Promise로 래핑하는 메서드를 만듭니다. 이 promise 객체는 xhr.onload 및 xhr.onerror에서 각각 완료 및 거부 상태의 전환 프로세스를 지정합니다. searchTwitter 함수는 promise 객체를 반환합니다. 그런 다음 loadTweets에서 then 메소드를 사용하여 완료 및 거부 상태에 해당하는 콜백 함수를 설정합니다.

function searchTwitter(term) {

    var url, xhr, results, promise;
    url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;
    promise = new Promise();
    xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);

    xhr.onload = function (e) {
        if (this.status === 200) {
            results = JSON.parse(this.responseText);
            promise.resolve(results);
        }
    };

    xhr.onerror = function (e) {
        promise.reject(e);
    };

    xhr.send();
    return promise;
}

function loadTweets() {
    var container = document.getElementById('container');
    searchTwitter('#IE10').then(function (data) {
        data.results.forEach(function (tweet) {
            var el = document.createElement('li');
            el.innerText = tweet.text;
            container.appendChild(el);
        });
    }, handleError);
}
로그인 후 복사

지금까지는 단일 Ajax 요청에 Promise 모드를 적용할 수 있었지만 Promise의 장점이 반영되지 않은 것 같습니다. 여러 Ajax 요청의 동시 협업을 살펴보겠습니다. 이 시점에서 호출 준비가 된 Promise 개체를 저장할 때 또 다른 메서드가 필요합니다. Promise가 불완전 상태에서 완료 또는 거부 상태로 변환되면 then 메소드의 해당 핸들러 함수가 호출됩니다. 모든 작업이 완료될 때까지 기다려야 하는 경우 when 메서드가 중요합니다.

Promise.when = function () {
    /* handle promises arguments and queue each */
};
로그인 후 복사

방금 IE10과 IE9의 콘텐츠를 얻은 시나리오를 예로 들면 다음과 같이 코드를 작성할 수 있습니다.

var container, promise1, promise2;
container = document.getElementById('container');
promise1 = searchTwitter('#IE10');
promise2 = searchTwitter('#IE9');
Promise.when(promise1, promise2).then(function (data1, data2) {

    /* Reshuffle due to date */
    var totalResults = concatResults(data1.results, data2.results);
    totalResults.forEach(function (tweet) {
        var el = document.createElement('li');
        el.innerText = tweet.text;
        container.appendChild(el);
    });
}, handleError);
로그인 후 복사

分析上面的代码可知,when函数会等待两个promise对象的状态发生变化再做具体的处理。在实际的Promise库中,when函数有很多变种,比如 when.some()、when.all()、when.any()等,读者从函数名字中大概能猜出几分意思来,详细的说明可以参考CommonJS的一个promise实现when.js。

除了CommonJS,其他主流的Javascript框架如jQuery、Dojo等都存在自己的promise实现。开发人员应该好好利用这种模式来降低异步编程的复杂性。我们选取Dojo为例,看一看它的实现有什么异同。

Dojo框架里实现promise模式的对象是Deferred,该对象也有then函数用于处理完成和拒绝状态并支持串联,同时还有resolve和reject,功能如之前所述。下面的代码完成了Twitter的场景:

function searchTwitter(term) {

    var url, xhr, results, def;
    url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;
    def = new dojo.Deferred();
    xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);

    xhr.onload = function (e) {
        if (this.status === 200) {
            results = JSON.parse(this.responseText);
            def.resolve(results);
        }
    };

    xhr.onerror = function (e) {
        def.reject(e);
    };

    xhr.send();
    return def;
}

dojo.ready(function () {
    var container = dojo.byId('container');
    searchTwitter('#IE10').then(function (data) {
        data.results.forEach(function (tweet) {
            dojo.create('li', {
                innerHTML: tweet.text
            }, container);
        });
    });
});
로그인 후 복사

不仅如此,类似dojo.xhrGet方法返回的即是dojo.Deferred对象,所以无须自己包装promise模式。

var deferred = dojo.xhrGet({
    url: "search.json",
    handleAs: "json"
});

deferred.then(function (data) {
    /* handle results */
}, function (error) {
    /* handle error */
});
로그인 후 복사

除此之外,Dojo还引入了dojo.DeferredList,支持开发人员同时处理多个dojo.Deferred对象,这其实就是上面所提到的when方法的另一种表现形式。

dojo.require("dojo.DeferredList");
dojo.ready(function () {
    var container, def1, def2, defs;
    container = dojo.byId('container');
    def1 = searchTwitter('#IE10');
    def2 = searchTwitter('#IE9');

    defs = new dojo.DeferredList([def1, def2]);

    defs.then(function (data) {
        // Handle exceptions
        if (!results[0][0] || !results[1][0]) {
            dojo.create("li", {
                innerHTML: 'an error occurred'
            }, container);
            return;
        }
        var totalResults = concatResults(data[0][1].results, data[1][1].results);

        totalResults.forEach(function (tweet) {
            dojo.create("li", {
                innerHTML: tweet.text
            }, container);
        });
    });
});
로그인 후 복사

上面的代码比较清楚,不再详述。

说到这里,读者可能已经对promise模式有了一个比较完整的了解,异步编程会变得越来越重要,在这种情况下,我们需要找到办法来降低复杂度,promise模式就是一个很好的例子,它的风格比较人性化,而且主流的JS框架提供了自己的实现。所以在编程实践中,开发人员应该尝试这种便捷的编程技巧。需要注意的是,promise模式的使用需要恰当地设置promise对象,在对应的事件中调用状态转换函数,并且在最后返回promise对象。

技术社区对异步编程的关注也在升温,国内社区也发出了自己的声音。资深技术专家老赵就发布了一套开源的异步开发辅助库Jscex,它的设计很巧妙,抛弃了回调函数的编程方式,采用一种“线性编码、异步执行”的思想,感兴趣的读者可以查看这里。

不仅仅是前端的JS库,如今火热的NodeJS平台也出现了许多第三方的promise模块,具体的清单可以访问这里。

위 내용은 JavaScript 비동기 프로그래밍의 Promise 패턴 샘플 코드에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

C++ 함수로 비동기 프로그래밍을 구현하는 방법은 무엇입니까? C++ 함수로 비동기 프로그래밍을 구현하는 방법은 무엇입니까? Apr 27, 2024 pm 09:09 PM

요약: C++의 비동기 프로그래밍을 사용하면 시간이 많이 걸리는 작업을 기다리지 않고 멀티태스킹이 가능합니다. 함수 포인터를 사용하여 함수에 대한 포인터를 만듭니다. 콜백 함수는 비동기 작업이 완료되면 호출됩니다. Boost::asio와 같은 라이브러리는 비동기 프로그래밍 지원을 제공합니다. 실제 사례에서는 함수 포인터와 Boost::asio를 사용하여 비동기 네트워크 요청을 구현하는 방법을 보여줍니다.

약속 지키기: 약속 이행의 장점과 단점 약속 지키기: 약속 이행의 장점과 단점 Feb 18, 2024 pm 08:06 PM

일상생활에서 우리는 약속과 이행 사이에서 종종 문제에 직면합니다. 개인적인 관계에서든 비즈니스 거래에서든 약속을 이행하는 것은 신뢰 구축의 핵심입니다. 그러나 헌신의 장단점은 종종 논란의 여지가 있습니다. 이 기사에서는 약속의 장단점을 살펴보고 약속을 지키는 방법에 대한 몇 가지 조언을 제공합니다. 약속된 혜택은 분명합니다. 첫째, 헌신은 신뢰를 구축합니다. 사람이 약속을 지키면 다른 사람들이 자신을 믿을 만한 사람이라고 믿게 만듭니다. 신뢰는 사람들 사이에 확립된 유대이며, 이는 사람들을 더 나은 사람으로 만들 수 있습니다.

간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 Jan 05, 2024 pm 06:08 PM

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

Promise.resolve()에 대해 자세히 알아보세요. Promise.resolve()에 대해 자세히 알아보세요. Feb 18, 2024 pm 07:13 PM

Promise.resolve()에 대한 자세한 설명에는 특정 코드 예제가 필요합니다. Promise는 비동기 작업을 처리하기 위한 JavaScript의 메커니즘입니다. 실제 개발에서는 순서대로 실행해야 하는 일부 비동기 작업을 처리해야 하는 경우가 종종 있으며, 이행된 Promise 객체를 반환하기 위해 Promise.resolve() 메서드가 사용됩니다. Promise.resolve()는 Promise 클래스의 정적 메서드입니다.

Java 프레임워크 비동기 프로그래밍의 일반적인 문제 및 솔루션 Java 프레임워크 비동기 프로그래밍의 일반적인 문제 및 솔루션 Jun 04, 2024 pm 05:09 PM

Java 프레임워크 비동기 프로그래밍의 3가지 일반적인 문제와 해결 방법: 콜백 지옥: Promise 또는 CompletableFuture를 사용하여 보다 직관적인 스타일로 콜백을 관리합니다. 리소스 경합: 동기화 기본 요소(예: 잠금)를 사용하여 공유 리소스를 보호하고 스레드로부터 안전한 컬렉션(예: ConcurrentHashMap) 사용을 고려하세요. 처리되지 않은 예외: 작업에서 예외를 명시적으로 처리하고 예외 처리 프레임워크(예: CompletableFuture.Exceptionally())를 사용하여 예외를 처리합니다.

golang 프레임워크는 동시성과 비동기 프로그래밍을 어떻게 처리합니까? golang 프레임워크는 동시성과 비동기 프로그래밍을 어떻게 처리합니까? Jun 02, 2024 pm 07:49 PM

Go 프레임워크는 Go의 동시성 및 비동기 기능을 사용하여 동시 및 비동기 작업을 효율적으로 처리하기 위한 메커니즘을 제공합니다. 1. 동시성은 Goroutine을 통해 달성되어 동시에 여러 작업을 실행할 수 있습니다. 2. 비동기 프로그래밍은 채널을 통해 구현됩니다. 작업을 차단하지 않고 실행할 수 있습니다. 3. HTTP 요청 동시 처리, 데이터베이스 데이터의 비동기 획득 등과 같은 실제 시나리오에 적합합니다.

JavaScript에서 HTTP 상태 코드를 쉽게 얻는 방법 JavaScript에서 HTTP 상태 코드를 쉽게 얻는 방법 Jan 05, 2024 pm 01:37 PM

JavaScript에서 HTTP 상태 코드를 얻는 방법 소개: 프런트 엔드 개발에서 우리는 종종 백엔드 인터페이스와의 상호 작용을 처리해야 하며 HTTP 상태 코드는 매우 중요한 부분입니다. HTTP 상태 코드를 이해하고 얻는 것은 인터페이스에서 반환된 데이터를 더 잘 처리하는 데 도움이 됩니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. HTTP 상태 코드란 무엇입니까? HTTP 상태 코드는 브라우저가 서버에 요청을 시작할 때 서비스가

Python 비동기 프로그래밍: 비동기 코드에서 효율적인 동시성을 달성하는 방법 Python 비동기 프로그래밍: 비동기 코드에서 효율적인 동시성을 달성하는 방법 Feb 26, 2024 am 10:00 AM

1. 비동기 프로그래밍을 사용하는 이유는 무엇입니까? 기존 프로그래밍에서는 차단 I/O를 사용합니다. 즉, 프로그램은 작업을 계속하기 전에 작업이 완료될 때까지 기다립니다. 이는 단일 작업에 적합할 수 있지만 많은 수의 작업을 처리할 때 프로그램 속도가 느려질 수 있습니다. 비동기 프로그래밍은 기존 차단 I/O의 한계를 깨고 비차단 I/O를 사용합니다. 즉, 프로그램은 작업이 완료될 때까지 기다리지 않고 실행을 위해 여러 스레드나 이벤트 루프에 작업을 배포할 수 있습니다. 이를 통해 프로그램은 여러 작업을 동시에 처리할 수 있어 프로그램의 성능과 효율성이 향상됩니다. 2. Python 비동기 프로그래밍의 기본 Python 비동기 프로그래밍의 기본은 코루틴과 이벤트 루프입니다. 코루틴은 함수가 일시 중지와 재개 사이를 전환할 수 있도록 하는 함수입니다. 이벤트 루프는 일정 관리를 담당합니다.

See all articles