const loader_1 = new GCodeLoader();
const loader_2 = new AMFLoader();
let ask_1 = true;
let ask_2 = true;
async function main() {
console.log('Start load')
if (ask_1){
const amfobject = await loader_1.loadAsync( './models/amf/rook.amf');
scene.add( amfobject );
console.log('on loader AMF', amfobject);
}
if (ask_2){
const object = await loader_2.loadAsync( 'models/gcode/benchy.gcode');
scene.add( object );
console.log('on loader GCode', object);
}
console.log('END load')
}
main();
Promise
- это просто хитрая надстройка надо коллбэками(полностью реализуемая на обычном js), позволяющая развернуть их порядок назначения - не более. async-await
- просто синтаксический сахар над Promise
, делающий оные менее многословными, но не меняющий механизма. PropsWithChildren<Props>
. Но под капотом он просто делает так: type PropsWithChildren<P> = P & { children?: ReactNode };
type TwitterProps = {
children: (user: string) => ReactNode
}
const response: ITwitter = ...
. Только если какая-нить хрень прилетит то может сломаться в рантайме, так что либо ты доверяешь серверу, либо используешь какую-нить либу для дополнительной проверки вживую.) type WritableFields<T> = Partial<Pick<T, WritableKeys<T>>>;
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options?: WritableFields<HTMLElementTagNameMap[K]>): HTMLElementTagNameMap[K] {
let element = document.createElement(tag)
if (options) {
// assign options
Object.assign(element, options);
}
return element
}
type WritableFields<T> = Partial<Pick<T, WritableKeys<T>>>;
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options?: WritableFields<HTMLElementTagNameMap[K]>): HTMLElementTagNameMap[K] {
let element = document.createElement(tag)
if (options) {
// assign options
let option: keyof typeof options;
for (option in options) {
element[option] = options[option]!; // ! - потому что теоретически ты можешь передать undefined явно, но морочиться с этим не стоит
}
}
return element
}
interface Foo {
foo: number;
}
тебе ничего не мешает передать ему {
foo: 1,
bar: 2
}
, т.к. данный объект расширяет интерфейс Foo и, соответственно, удовлетворяет ему. Получается, что внутри функции typescript никак не может быть уверен, что ключи указанные в интерфейсе - это ВСЕ ключи, а значит не может быть уверен, что при переборе и присвоении не будет присвоено что-то лишнее. (Это не говоря уже о прототипах, геттерах и прочем) Vue
появились дополнительные свойства типа $route
. Надо отдельно подключать декларации вручную, либо следовать инструкции выше. getMediaUrls
пока не будет данных. getMediaUrls
должно быть computed
свойство mediaUrls
; во-вторых: скрывайте в шаблоне отображение пока не появятся данные: v-if="currentProductData"
/v-if="currentProductData.length"
и показывайте вместо этого какой-нить loader, Vue не запросит то, что скрыто под v-if
пока условие не станет верным.getMediaUrls
в mounted
и разрывать асинхронную цепочку. Вызывайте его сразу в getProductData
, либо если currentProductData
может меняться в иных случаях - сделайте, опять же, computed свойством. В крайнем случае можно вызывать его, повесив watch
на currentProductData
, но computed
лучше. http_response_code
редиректа (30х).setTimeout
вместо функции, использовано document.location
вместо window.location
.<form>
<input />
<button onclick="alert('Такие дела')"></button>
</form>
<div class="row">
<div class="input-field col s12">
<select class="group-select" ref="select2" v-model="depart_select">
<optgroup v-for="department in departments" :key="department.id" :label="department.NameOtdel">
<option v-for="{NamePodrazdel, id} in department.NamePodrazdel" :key="id" :value="id">{{ NamePodrazdel }} </option>
</optgroup>
</select>
<label>Структурное подразделение</label>
</div>
</div>
anotherReplace: [/\(\.\*\)$/, ':name']
function strReplace = (str, anotherReplace = null) => {
str = str
.replace(что-то заменяем)
.replace(eщё что меняем);
if (anotherReplace)
str = str.replace(anotherReplace[0], anotherReplace[1]);
return str;
}