지금이 순간,나는'm 사용하려고 시도하는async/기다리고 있
클래스 내에서 생성자 기능입니다. 이것은 그래서 나는 내가 원하는 것을 얻을 수 있는 사용자 정의의 전자 메일을`태그에 대한 전자 프로젝트 I'm 에 노력하고 있습니다.
customElements.define('e-mail', class extends HTMLElement {
async constructor() {
super()
let uid = this.getAttribute('data-uid')
let message = await grabUID(uid)
const shadowRoot = this.attachShadow({mode: 'open'})
shadowRoot.innerHTML = `
<div id="email">A random email message has appeared. ${message}</div>
`
}
})
에서는 순간 그러나,프로젝트 작동하지 않는,다음과 같은 오류가:
Class constructor may not be an async method
이 우회하는 방법은 이렇게 사용할 수 있는 비동기/리에 이? 를 요구하는 대신 콜백 또는.다음()?
이 수 있지 않작동합니다.
는async
키워드 할 수 있습니다기다리고 있
에서 사용할 수 있는 기능으로 표시비동기
하지만 그것 또한을 변환하는 기능으로 약속이 생성기입니다. 그래서 함수로 표시`async 이 약속입니다. 에서 생성자를 다른 한편으로 객체를 반환합니다 그것은 구성하자. 따라서 우리가 당신이 원하는 상황을 모두 객체를 반환하고 약속하는 불가능한 상황이다.
만 사용할 수 있습니다 async/기다리고 당신이 사용할 수 있는 약속이 있기 때문에 그들은 기본적으로 구문 설탕에 대한 약속입니다. 할 수 있't 약속을 사용에서 생성자 때문에 생성자를 반환해야할 객체를 구성하지 않 약속입니다.
두 가지가 있는 디자인 패턴을 극복하는 이 둘 모두를 발명하기 전에 약속이 있었다.
init()
기능이 있습니다. 이처럼 비트 jQuery's.준비()
. 체를 만들 내에서만 사용할 수 있습 it's owninit
또는준
기능:사용법:
var myObj=new myClass(); myObj.init(function(){ //안에 여기를 사용할 수 있습 myObj });
구현:
class myClass{ 생성자를(){
}
init(callback){ //뭔가 비동기 및 통화 callback: 콜백입니다.bind(이)(); } }
사용법:
myClass.구축().다음(function(myObj){ //myObj 반환에 의해 약속 //지에 의해 생성자 //또는 빌더 });
//으로 비동기/기다리고 있:
비동기 기능 foo(){ var myObj=리 myClass.구축(); }
구현:
class myClass{ constructor(async_param){ if(typeof async_param==='undefined'){ throw new 오류가('할 수 없는 직접적으로 호출 될'); } }
정적 구축(){ 반 doSomeAsyncStuff() .다음(function(async_result){ return new myClass(async_result); }); } }
구현 async/기다리고 있:
class myClass{ constructor(async_param){ if(typeof async_param==='undefined'){ throw new 오류가('할 수 없는 직접적으로 호출 될'); } }
정적 비동기를 구축(){ var async_result=리 doSomeAsyncStuff(); return new myClass(async_result); } }
Note:지만 위의 예에서 우리는 약속을 사용해 비동기 builder 그들은 엄밀히 말하면 필요하다. 당신은 쉽게 쓰는 빌더 받을 콜백입니다.
이는 아무것도 전혀으로 비동기를 생성자 하지만 무엇 키워드이
실제로 의미(수 있는 조금 놀라운 사에서 나오는지 자동 해상도의 방법 이름,그 언어는't 필요한이
키워드).
이
키워드를 참조하는 인스턴스화체입니다. 지 않습니다. 따라서할 수 없습니다 일반적으로 사용하는이 내에서
정체되는 기능 때문에 정전기 방지 기능이 제한되지 않는 모든 개체나 바인딩에 직접 클래스입니다.
말하자면,다음 코드:
class A {
static foo () {}
}
당신은 할 수 없:
var a = new A();
a.foo() // NOPE!!
대신 당신을 호출해야로 그것:
A.foo();
따라서,다음과 같은 코드에 오류가 발생합니다:
class A {
static foo () {
this.bar(); // you are calling this as static
// so bar is undefinned
}
bar () {}
}
그것을 해결할 수 있bar
어느 일반 기능 또는 정적 방법:
function bar1 () {}
class A {
static foo () {
bar1(); // this is OK
A.bar2(); // this is OK
}
static bar2 () {}
}
당신할 수 있니다 기본적으로:
class AsyncConstructor {
constructor() {
return (async () => {
// All async code here
this.value = await asyncFunction();
return this; // when done
})();
}
}
클래스를 만드는 데 사용:
let instance = await new AsyncConstructor();
참고:를 사용해야 하는 경우 슈퍼,당신을 호출할 수 없습니다 그것에서 비동기 콜백입니다. 당신이 전화를 그 밖의 그래서 그것이 솔루션을 발견 100%완벽하지만 내 생각에는것은 매우 유용하고 나는 그것을 사용하는 모든간에 나의 코드입니다.
귀하의 의견에 따라,당신은 아마 어떤 다른 모든 HTMLElement 자산 로드 않:들에게 생성자를 시작이드 로딩 작업을 생성,로드 또는 오류 이벤트에 따라 결과입니다.
그렇습니다,그 방법을 사용하여 약속,그러나 그것은 또한"을 하는 것과 같은 방법으로 다른 모든 HTML 요소",그래서 당신이'시에서 좋은 회사입니다. 예를 들어:
var img = new Image();
img.onload = function(evt) { ... }
img.addEventListener("load", evt => ... );
img.onerror = function(evt) { ... }
img.addEventListener("error", evt => ... );
img.src = "some url";
이 개막 비동기의 부하를 원하는 자산을 때,그것이 성공하면,종료에onload
그리고 그것은 잘못되면,종료에onerror
. 그래서,당신의 자신의 클래스에 이렇게도:
class EMailElement extends HTMLElement {
constructor() {
super();
this.uid = this.getAttribute('data-uid');
}
setAttribute(name, value) {
super.setAttribute(name, value);
if (name === 'data-uid') {
this.uid = value;
}
}
set uid(input) {
if (!input) return;
const uid = parseInt(input);
// don't fight the river, go with the flow
let getEmail = new Promise( (resolve, reject) => {
yourDataBase.getByUID(uid, (err, result) => {
if (err) return reject(err);
resolve(result);
});
});
// kick off the promise, which will be async all on its own
getEmail()
.then(result => {
this.renderLoaded(result.message);
})
.catch(error => {
this.renderError(error);
});
}
};
customElements.define('e-mail', EmailElement);
그리고 당신은 만들 renderLoaded/renderError 기능격으로 이벤트를 호출하고 그림자 dom:
renderLoaded(message) {
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<div class="email">A random email message has appeared. ${message}</div>
`;
// is there an ancient event listener?
if (this.onload) {
this.onload(...);
}
// there might be modern event listeners. dispatch an event.
this.dispatchEvent(new Event('load', ...));
}
renderFailed() {
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<div class="email">No email messages.</div>
`;
// is there an ancient event listener?
if (this.onload) {
this.onerror(...);
}
// there might be modern event listeners. dispatch an event.
this.dispatchEvent(new Event('error', ...));
}
또한 참고 변경하는id
a클래스
,기 때문에 당신이 쓰지 않는 한 어떤 이상한 코드만 허용한 단일의 인스턴스의<e-mail>
요소로 페이지에서,당신이 할 수 있't 에 고유 식별자를 사용하고 다음에 할당을 무리의 요소입니다.
기 때문에 비동기 기능에 약속을 만들 수 있습니다,정전기 방지 기능에서 당신의 클래스는 실행하는 비동기 기능을 반환합니다 클래스의 인스턴스:
class Yql {
constructor () {
// Set up your class
}
static init () {
return (async function () {
let yql = new Yql()
// Do async stuff
await yql.build()
// Return instance
return yql
}())
}
async build () {
// Do stuff with await if needed
}
}
async function yql () {
// Do this instead of "new Yql()"
let yql = await Yql.init()
// Do stuff with yql instance
}
yql()
전화자 yql=리 Yql.init()
에서는 비동기 기능이다.
이 테스트-케이스에 기반@Downgoat's답변.
에서 실행 및 라이브러리.
이 Downgoat's 코드는 곳에 비동기는 부분에 의해 제공되는setTimeout()
호출합니다.
'use strict';
const util = require( 'util' );
class AsyncConstructor{
constructor( lapse ){
this.qqq = 'QQQ';
this.lapse = lapse;
return ( async ( lapse ) => {
await this.delay( lapse );
return this;
})( lapse );
}
async delay(ms) {
return await new Promise(resolve => setTimeout(resolve, ms));
}
}
let run = async ( millis ) => {
// Instatiate with await, inside an async function
let asyncConstructed = await new AsyncConstructor( millis );
console.log( 'AsyncConstructor: ' + util.inspect( asyncConstructed ));
};
run( 777 );
내가 사용하는 경우가 DAOs 서버 측의 웹 응용 프로그램입니다. 볼로 DAOs,그들 각각의 하나에 연결된 기록을 형식,내 경우에는 MongoDB 컬렉션을 처럼 예를 들어 요리입니다. A cooksDAO 인스턴스를 보유하고있는 요리를's data. 에서 내 불안한 마음이 나는 것스를 인스턴스화할 수 있는 요리사's DAO 을 제공하 cookId 으로 인수하고,인스턴스를 만듭 개체고 채우리's data. 따라서 실행할 필요가 비동기는 물건으로 생성자입니다. 쓰고 싶다:
let cook = new cooksDAO( '12345' );
을 사용할 수 있는 속성을 다음과 같요리입니다.getDisplayName()
.
이 솔루션과 함께 내가 할 일:
let cook = await new cooksDAO( '12345' );
는 매우 유사하다 이상적입니다.
또한,저는 이것을 할 필요가 내부에는비동기
기능이 있습니다.
내 B-계획을 떠나는 데이터 로드의 생성자를 기반으로,@slebetman 제안을 사용하여 초기화 함수,그리고 다음과 같은 것이 가능합니다.
let cook = new cooksDAO( '12345' );
async cook.getData();
지 않는't 휴식 규칙이 있습니다.
할 수 있는 경우피연장
,피할 수 있습니다 클래스는 모두 함께 사용하는 함수 구성으로 constructors. 변수를 사용할 수 있습 범위에 대 클래스의 구성원:
js 비동기 기능 buildA(...){ const 데이터 기다리고 가(...); return{ getData:function(){ 데이터는 반환; } } }
고 간단으로 사용
js const a=리 buildA(...);
당신이'다시 사용하여 타이프 라이터 또는 교류할 수 있습도 적용 인터페이스의 constructors `` 인터페이스 A{ getData:체; }
비동기 기능 buildA0(...):Promise{...} 비동기 기능 buildA1(...):Promise{...} ... ``
변화에 builder 패턴 호출을 사용하여():
function asyncMethod(arg) {
function innerPromise() { return new Promise((...)=> {...}) }
innerPromise().then(result => {
this.setStuff(result);
}
}
const getInstance = async (arg) => {
let instance = new Instance();
await asyncMethod.call(instance, arg);
return instance;
}
@slebetmen's 를 받아들이 대답을 잘 설명 왜 이는't work. 이외에 두 가지 패턴을 제시에 응답하는,또 다른 옵션은 만 액세스 비동기 속성을 통해 사용자 지정 async getter. 생성자를()할 수 있습을 트리거하는 비동기를 창조의 특성,하지만 getter 는지 확인합하는 경우 사용할 수 있는 속성을 사용 전에 또는 반환합니다.
이러한 접근 방식은 특히 유용하고 싶을 때 초기화 글로벌 객체를 한 번에 시작하고,당신은 그것을 할 수 내부 모듈이 있다. 대신 초기에index.js
그리고 전달하는 인스턴스에서 필요한 장소,그것은 단순히require
당신의 모듈을 어디서든 세계체가 필요합니다.
사용법
const instance = new MyClass();
const prop = await instance.getMyProperty();
구현
class MyClass {
constructor() {
this.myProperty = null;
this.myPropertyPromise = this.downloadAsyncStuff();
}
async downloadAsyncStuff() {
// await yourAsyncCall();
this.myProperty = 'async property'; // this would instead by your async call
return this.myProperty;
}
getMyProperty() {
if (this.myProperty) {
return this.myProperty;
} else {
return this.myPropertyPromise;
}
}
}
을 추가해야 한다음
기능을 인스턴스입니다. 약속
은 그것으로 인식 thenable 체약속한다.를 해결하
자동으로
const asyncSymbol = Symbol();
class MyClass {
constructor() {
this.asyncData = null
}
then(resolve, reject) {
return (this[asyncSymbol] = this[asyncSymbol] || new Promise((innerResolve, innerReject) => {
this.asyncData = { a: 1 }
setTimeout(() => innerResolve(this.asyncData), 3000)
})).then(resolve, reject)
}
}
async function wait() {
const asyncData = await new MyClass();
alert('run 3s later')
alert(asyncData.a)
}
다른 대답이 없는 분명합니다. 단순히 부르는 비동기 기능에서 생성자:
constructor() {
setContentAsync();
}
async setContentAsync() {
let uid = this.getAttribute('data-uid')
let message = await grabUID(uid)
const shadowRoot = this.attachShadow({mode: 'open'})
shadowRoot.innerHTML = `
<div id="email">A random email message has appeared. ${message}</div>
`
}