JavaScript로 작성한 Windows 스토어 앱과 일반적인 웹앱

JavaScript를 사용하는 Windows 스토어 앱과 일반적인 웹앱

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows에서 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

이 항목에서는 JavaScript로 작성된 기존 웹앱에서 사용되는 코딩 스타일을 JavaScript를 사용하는 Windows 스토어 앱과 비교하여 그 차이점에 대한 정보를 제공합니다. Windows에 최적화된 코드가 플랫폼 간에 쉽게 마이그레이션되는 앱과 어떻게 관련이 있는지를 웹 개발자가 이해할 수 있도록 지침을 제공합니다. 이 문서를 읽는 독자는 JavaScript 프로그래밍과 W3C(World Wide Web Consortioum) 표준에 익숙하다고 가정합니다.

소개

Windows 8은 Windows용 새 Windows 스토어 앱을 빌드하는 플랫폼을 제공합니다. Windows 스토어 앱은 ECMAScript 5를 준수하는 JavaScript를 비롯하여 다양한 프로그래밍 언어로 작성할 수 있습니다.

Windows 런타임 앱은 표준 기반 웹 기술의 강점과 편재성(ubiquity), 간소성과 결합된 Windows의 강점과 폭넓은 기능을 활용할 수 있습니다.

사실 JavaScript로 앱을 제작할 때 개발자는 기존 웹 표준을 선택할 수도 있습니다. 이렇게 하면 다른 표준을 준수하는 플랫폼과 상호 운용성이 높아집니다. 그러나 Windows 런타임에서도 Windows 플랫폼에 최적화된 Windows 스토어 앱을 JavaScript로 빌드할 수 있습니다.

목적에 따라 앱을 설계하는 최선의 방법이 달라집니다. 다음 참고 자료를 검토하면 좀 더 쉽게 최선의 방법을 선택할 수 있습니다.

Windows 런타임 JavaScript 디자인 패턴

Windows 런타임은 프로그래머가 기존의 웹 개발 환경을 활용할 수 있는 개발 환경을 제공합니다. 대체로 Windows 런타임 API는 숙련된 웹 개발자들에게 친숙하게 느껴질 것입니다. 이 API는 표준 기반 웹 개발 API를 확장한 것이며 기존 코드가 작동하게 하기 위해 개발자가 외부 구조를 강제로 가져오지 않고도 필요할 때 사용할 수 있습니다. 그러나, Windows 런타임 API는 개발자에게 플랫폼의 일부 측면을 더 세부적으로 제어할 수 있는 권한을 줍니다(예: I/O 장치와 연결).

Windows 런타임은 또한 특정 W3C 사양에 정의된 패턴에 익숙한 웹 개발자에게는 새로운 일부 코딩 패턴과 이 패턴을 바탕으로 빌드된 가장 일반적인 프레임워크 일부를 Windows 플랫폼에 도입합니다.

다음 몇 섹션에서는 이 패턴에 대해 살펴보고 그 원리에 대해 간략히 설명합니다.

웹에서의 비동기 프로그래밍

웹앱은 그 특성상 요청과 응답 간의 지연 시간이 로컬 리소스에만 액세스하는 앱보다 훨씬 더 길 가능성이 있습니다. 원격 서버에 대한 동기(차단) 호출은 웹앱의 UI를 정지시켜 사용자 환경에 받아들이기 어려운 영향을 줍니다. 문제 해결을 위해 다중 스레딩을 사용할 수 있지만 아키텍처의 복잡성으로 인해 가격이 상당히 증가합니다. 이것이 JavaScript API가 전형적으로 비동기 프로그래밍 구문을 구현하고, 대부분의 표준 API가 이를 널리 활용하는 이유입니다.

Windows 런타임은 전면적으로 비동기 프로그래밍을 채택하여 풍부한 I/O 기능을 개발자에게 제공하고 이 개념을 새로운 종류의 디스크, 네트워크 및 장치 조작에 적용합니다. 이미 여러 프로그래밍 언어와 일부 일반적인 JavaScript 프레임워크에서 보여진 검증된 패러다임을 사용합니다.

개발자는 항상 동일한 기본 템플릿을 사용하여 FileReader, Web Sockets, Geolocation, IndexedDB 등의 다양한 구성 요소를 활용하여 앱을 빌드할 수 있습니다. 결과적으로 더 쉽게 코드를 읽고 유지 관리할 수 있습니다(특히 여러 비동기 작업이 서로 의존하고 있는 경우). Windows 런타임은 코드에서 단계적으로 연속되는 콜백 흐름(전형적으로 숙련된 개발자에게도 쉽지 않은 작업)을 훨씬 쉽게 더 직관적으로 따릅니다.

Promises

Windows 8에서 JavaScript의 비동기 프로그래밍은 다른 일반적인 JavaScript 도구 키트에서도 사용되는 Promises 패턴으로 처리됩니다. Promises는 비동기 결과를 프로그램하는 일관된 방법을 제공하고, 비동기 작업을 구성하는 기능 그리고 통합된 비동기 오류 처리 모델을 제공합니다.

Promise란?

Promise는 아직 컴퓨팅되지 않은 값, 아직 발견되지 않은 오류, 아직 수행되지 않은 작업을 나타내는 개체입니다.

  • Promise는 비동기 구성 요소를 사용하는 프로그래밍 모델을 간소화하는 메커니즘입니다.
  • Promise는 비동기 작업에 대해 구성 가능한 래퍼를 만드는 수단입니다.

Promise 사용 방법

Promise 사용을 위한 API는 간단합니다. 실제로 이 API에는 두 개의 인스턴스 메서드가 있습니다.



.then(onComplete, onError, onProgress)
.cancel()


.then() 메서드는 약속된 값을 사용할 수 있는 어느 시점, 값을 계산하는 중 오류가 발생했을 때 또는 사용할 수 있는 상태까지 진행되었을 때 호출되는 처리기를 입력으로 사용합니다. then()에서 반환하는 값은 onComplete 또는 onError 처리기의 호출에서 반환하는 값의 Promise입니다. onComplete 또는 onError 처리기를 실행하는 동안 예외가 발생하면 반환된 Promise가 예외 값인 오류 값으로 실행됩니다.

각 처리기에는 그 처리기와 관련된 상태를 나타내는 단일 값이 전달됩니다.

  • onComplete 처리기에서 이 값은 약속된 값입니다.
  • onError 처리기에서 이 값은 발생한 오류입니다.
  • onProgress 처리기에서 이 값은 작업에서 정의한 어떤 값(기본적으로는 약속된 값과 관련된 값)입니다.

인수는 정의되어 있지 않을 수도 있습니다. onComplete 인수가 정의되지 않으면 개발자가 다음을 전달한 것과 마찬가지입니다.



function (v) { return v; }


onError 인수가 정의되지 않으면 개발자가 다음을 전달한 것과 마찬가지입니다.



function (e) { throw e; }


onProgress 인수가 정의되지 않으면 개발자가 다음을 전달한 것과 마찬가지입니다.



function () { }


.cancel() 메서드는 Promise 및 Promise가 의존하는, 계산되지 않은 모든 작업을 무시하라고 요청하는 데 사용할 수 있습니다.

Promise는 구성 가능한 비동기를 쉽게 만들어 줍니다. 예를 들어 Windows 런타임에서 파일의 텍스트를 읽으려면 많은 비동기 작업이 필요합니다. Promise 호환 언어를 사용하면 다양한 API를 간단한 readAllTextAsync() 함수로 쉽게 구성할 수 있습니다.



function readAllTextAsync(path) {
    return Windows.Storage.getFileItemFromPathAsync(path).
       then(function (item) { 
           var mode = Windows.Storage.FileAccesMode.read;
           return item.getStreamAsync(mode);
       }).
       then(function (seeker) {
           var bbrw 
         = new Windows.Storage.BasicBinaryReaderWriter();
           return bbrw.readStringAsync(seeker.getReaderAt(0));
       });
}


readAllTextAsync() 사용자는 이제 파일의 경로와 결과를 가지고 수행할 작업에 대해서만 걱정하면 됩니다.



    readAllTextAsync(path).
        then(console.log);


.then 구문 대신 콜백을 사용하는 더 일반적인 코딩 스타일로 다시 패키지한다면 이 기능은 훨씬 더 복잡해지고 오류가 발생하기 쉽습니다. 이 패러다임에서 비동기 호출의 연결 방식은 아래와 비슷합니다. 특히 onErroronProgress 절이 추가되는 경우 유지하기가 더 힘들어집니다.



doSomethingAsync(1, 2, function (result) {
    doSomethingAsync(result, 5, function (result) {
        doSomethingAsync(result, 10, function (result) {
            console.log(value);
        });
    });
});


DOM 이벤트

W3C 문서는 DOM 이벤트를 "이벤트 처리기의 등록을 허가하고, 트리 구조를 통한 이벤트 흐름을 설명하며 각 이벤트에 대한 기본 문맥 정보를 제공하는 일반적인 플랫폼이자 언어 중립적인 이벤트 시스템"으로 정의합니다. Windows 런타임은 DOM Level 3 이벤트 사양의 관련 하위 집합을 구현합니다.

특히 Windows 스토어 앱에서 시스템 이벤트는 DOM 이벤트와 같은 방식으로 표현됩니다. 따라서 개발자는 addEventListener()removeEventListener() 함수와 이를 관리하는 관련 시맨틱을 호출할 수 있습니다. 그 결과로, 새로운 기술을 배우지 않고도 UI에 어떤 일이 일어나는지, 프로그램이 어떻게 응답해야 하는지에 대해 매우 세부적으로 제어할 수 있습니다.

DOM 이벤트 사양과 다른 한 가지 중요한 부분은 Windows 런타임은 Windows 스토어 앱이 인위적으로 이벤트를 발생시키는 것을 막는다는 점입니다(예: 마우스 및 키보드 이벤트) . 이런 이유로 dispatchEvent() 메서드는 지원되지 않습니다. 이를 선택하는 주요 이유 중 하나가 보안 및 코드 유지 관리에 대한 고려였습니다.

이벤트는 UI 테스팅 및 자동화의 목적으로 개발자에 의해 인위적으로 생성됩니다. 그러나 대부분의 경우 대신 적용할 올바른 디자인 패턴이 있다면 이것은 불필요한 작업입니다. Windows 스토어 앱 개발자에게 MVC 패턴을 사용하는 등과 같은 기본 데이터 모델과는 완전히 다른 관점에서 앱을 설계하도록 권장하고 있습니다. 그렇게 하면 자동화는 GUI 수준에서 사용자를 가장하는 대신 직접 비즈니스 논리를 대상으로 지정할 수 있습니다.

버블링, 캡처 그리고 이벤트 처리기로 전달될지 모르는 특정 관련 속성 역시 Windows 런타임 API 디스패치 워크플로의 일부가 아닙니다. 이것은 Windows 런타임 이벤트가 트리 구조 DOM과 본질적으로 관련이 없다는 사실로 보면 자연스러운 결과입니다. 그러므로 일반적으로 버블되어야 하는 이벤트에는 개체 계층 구조가 없습니다.

네임스페이스

Windows 런타임은 800개 이상의 개별 클래스와 ENUM으로 구성된 상당히 큰 플랫폼입니다. 잠재적인 미래 성장도 고려하면서, 가능한 가장 직관적인 네임스페이스 구조를 얻기 위해서는 디자인 과정에서 신중한 고려가 필요했습니다.

일반적으로 W3C 사양은 글로벌 네임스페이스에 추가됩니다. 이 글로벌 네임스페이스 오염은 편리할 수 있지만 이미 API의 수가 웹 플랫폼 상에서 빠른 속도로 증가하고 있어 확장성 문제에 직면하고 있습니다. Windows 런타임의 사용 크기, Windows와 웹 플랫폼의 독립적 진보를 고려하면 Windows API를 글로벌 환경에 공개하는 것은 비현실적일 것입니다.

그 결과로 얻은 것이 API가 쉽게 검색할 수 있는 기능 영역으로 분류된 네임스페이스 계층 구조입니다. 이 계층 구조는 너무 평면적이지도 않고(너무 많은 개체가 루트 수준에 정렬되어 혼란스럽고 비실용적), 너무 깊지도 않습니다(읽기 힘들거나 비직관적인 코드). 어떤 경우에는 매우 다른 작업을 수행하는 클래스들의 이름이 비슷하여 생기는 혼란을 피하기 위해 의도적으로 차이를 만듭니다. 모든 경우에 Windows 런타임 개체와 표준 기반 개체 사이에는 명확한 차이가 있습니다. 이 신중한 균형 작업은 웹에서 볼 수 있는 브라우저 프로그래밍 예제와는 다소 다른 명명 구조를 만들었습니다.

예를 들어 W3C Geolocation 사양에 설명되어 있는 Geolocation 기능에 액세스하려면 다음을 호출해야 합니다.



navigation.geolocation


반면 Windows 런타임은 이 기능을 이렇게 표시합니다.



Windows.Devices.Geolocation.Geolocator()


가장 명확한 차이점은 "Windows" 루트 네임스페이스의 사용입니다. 이는 Windows 런타임에서만 표시하는 전역 개체입니다. 클래스를 이 네임스페이스 아래에 두는 가장 중요한 이유는 Windows의 고유한 기능을 활용하는 요소를 명확하게 구별하기 위해서입니다. 또한 간소한 휴대성을 위해 웹 표준에 기반한 기능을 함께 사용할 수 있습니다.

다단계 네임스페이스를 모두 적을 필요가 없는 경우에는 아래와 같이 코드 표시 수준을 최소화하기 위해 프로그램을 시작할 때 네임스페이스 별칭을 사용할 수 있어서 편리합니다.



var geo = Windows.Devices.Geolocation;
///...
var x = new geo.Geolocator();


또한 네임스페이스를 사용하면 개발 도구 및 문서에서 API를 더 쉽게 검색할 수 있습니다.

열거

웹 표준으로 정의된 개체는 다양한 방법론을 사용한 허용 값의 소규모 조합에서 속성을 설정합니다. 때때로 열거를 사용하지만 문자열도 종종 허용됩니다. 이렇게 하는 중요한 이유는 새로운 속성이 표준화되기 전에 다른 조직에서 실험할 수 있는 여지를 남기기 위해서입니다.(간단한 문자열을 사용하여 할당하고 지정하는 것이 더 쉽습니다.) 부분적으로는 Windows 런타임에서는 그럴 필요가 없기 때문에 열거를 사용하는 경향이 더 많습니다.

이렇게 하면 다음과 같은 단순한 문을 교환합니다.



reader.readAsText(readFile, "UTF-16");


Windows 런타임 구문으로 대체하면 다음과 같습니다.



reader.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf8;
reader.readString(someValue);


이 구문이 더 견고하며, 맞춤법 오류나 기타 문제가 포함될 가능성이 더 적습니다. 매개 변수의 유효한 값 역시 훨씬 검색하기 쉽습니다. 또한 열거는 Windows 플랫폼에서 지원하는 프로그래밍 언어의 일관성과 상호 운용성을 유지합니다.

생성자

비록 W3C 사양이 생성자 사용을 비롯하여 여러 가지 다른 스타일을 사용하여 개체를 만들지만, 많은 경우 암시적으로 인스턴스화된 단일 JavaScript 개체를 설명하고 여러 메서드와 속성을 통해 자신의 역할을 수행합니다. 이 항목의 이전 섹션에서 언급했던 탐색기 개체가 그 예입니다.

Windows 런타임에서는 비슷한 API가 다르게 표시되기도 합니다. 가능한 한 언제나 기존 웹 표준과의 일관성을 추구했지만 결국에는 각 기능에 가장 적합한 디자인이 채택되었습니다. 특히 Windows 런타임은 관련이 있지만 특수화된 클래스의 조합으로 더 세분화되고 각 클래스는 일반적으로 고유한 생성자 또는 정적 팩터리 메서드를 통해 인스턴스화됩니다.

Visual Studio는 Intellisense와의 통합을 통해 이러한 구문의 생성을 크게 간소화합니다(코드 완성). 또한 구문적 실수가 바로 식별되므로 개발자가 더 안정적으로 빌드하고 실행할 수 있는 코드를 빌드하도록 도와줍니다.

관련 항목

HTML5 DOM 수준 3 이벤트 사양
일반 JS Promises/제안된 표준 Wiki

 

 

표시:
© 2018 Microsoft