Typescrip異步函數Promise使用方式
Typescrip異步函數Promise
var p = new Promise(function (resolve, reject) {
var x = 1;
if (x > 0) {
resolve({ msg: '異步調用成功', data: { x: 1, y: 2 } });
}
else {
reject({ msg: '異步調用失敗', data: {} });
}
});
//異步調用結果
p.then(function (data) {
console.log('OK');
console.log(data);
//console.log(data.msg,data.data);
})["catch"](function (err) {
console.log(err);
});
//異步函數
function promiseFunc(t) {
console.log("".concat(t / 1000, "\u79D2\u540E\u8C03\u7528\u5F02\u6B65"));
return new Promise(function (resolve, reject) {
setTimeout(resolve, t, '異步調用完成');
});
}
//調用異步函數
promiseFunc(1000).then(function (value) { console.log(value); });
var promiseAction = new Promise(function (resolve, reject) {
console.log('執(zhí)行了一些異步操作...');
resolve('異步操作完成了!');
});
promiseAction.then(function (value) { console.log(value); });
// @ts-ignore
// const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
// let getDataAsync=(url)=>{
// let p = new Promise((resolve, reject) => {
// let c =new XMLHttpRequest();
// c.open('GET',url);
// c.onreadystatechange = h;
// c.responseType = 'json';
// c.setRequestHeader('Accept','application/json');
// c.send();
// function h(){
// if(this.readyState!==4){return;}
// if (this.status===200){
// console.log('請求成功返回:',this.status);
// resolve(this.response);
// }else {
// reject(new Error(this.statusText));
// }
// }
// });
// return p;
// };
// getDataAsync('http://192.168.31.180/data.json')
// .then(data=>{console.log(data);})
// .catch(err=>{console.log(err);});
//通過https加載json數據
var url = 'https://img-home.csdnimg.cn/data_json/toolbar/toolbar1105.json';
var url1 = 'https://mp-api.iqiyi.com/base/api/1.0/get_role';
var GetJsonData = function (url) {
var https = require('https');
https.get(url, function (response) {
var data = '';
//數據正在接收中...
response.on('data', function (chunk) {
data += chunk;
});
//數據接收完成
response.on('end', function () {
console.log('同步請求數據完成:', JSON.parse(data));
});
}).on("error", function (error) {
console.log("Error: " + error.message);
});
};
GetJsonData(url);
//異步請求JSON數據實現(xiàn)
var GetJsonDataAsync = function (url) {
var https = require('https');
return new Promise(function (resolve, reject) {
https.get(url, function (response) {
var data = '';
//數據正在接收中...
response.on('data', function (chunk) {
data += chunk;
});
//數據接收完成
response.on('end', function () {
//console.log(JSON.parse(data));
resolve(data); //數據接收完成
});
}).on("error", function (error) {
console.log("Error: " + error.message);
reject(new Error(error.message));
});
});
};
//異步調用
GetJsonDataAsync(url).then(function (value) {
console.log("======================下面為異步加載數據=================================");
if (typeof value === "string") {
console.log('異步加載請求數據完成:', JSON.parse(value));
}
})["catch"](function (err) { console.log(err); });
//通過request庫請求json數據,使用前 sudo npm i -g request安裝包
var request = require('request');
request(url, function (error, response, body) {
console.error('錯誤:', error);
console.log('狀態(tài)碼:', response && response.statusCode);
console.log('數據:', JSON.parse(body));
});
//異步方式
var RequestJsonAsync = function (url) {
return new Promise(function (resolve, reject) {
request(url, function (e, r, d) {
if (null != e) {
reject(new Error(e));
}
else {
resolve(JSON.parse(d));
}
});
});
};
RequestJsonAsync(url).then(function (value) {
console.log("==============request異步加載json===============================");
console.log(value);
})["catch"](function (err) { console.log(err); });
//nodejs needle庫使用 ,使用前 npm i needle --save 安裝包
var needle = require('needle');
needle.get(url, function (error, response) {
if (!error && response.statusCode == 200)
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", response.body);
});
//異步模式
needle('get', url, { json: true }).then(function (resp) {
if (resp.statusCode == 200) {
console.log(">>>>>>>>>>>>>>異步模式>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", resp.body);
}
})["catch"](function (err) { console.log(err); });
//使用axios庫使用,axios直接異步 使用前安裝 npm i -g axios --save
var axios = require('axios');
axios.get(url)
.then(function (res) {
console.log(res);
})["catch"](function (err) {
console.log(err);
});
//axios支持多請求并發(fā)
axios.all([
axios.get(url),
axios.get(url1)
]).then(axios.spread(function (res1, res2) {
console.log(res1);
console.log(res2);
}))["catch"](function (err) {
console.log(err);
});
//supertaget庫使用
var superagent = require('superagent');
superagent.get(url)
.end(function (err, res) {
if (err) {
return console.log(err);
}
console.log("superagent庫調用==========>", res.body);
});
//fetch庫使用 使用前安裝 npm i node-fetch 3x版本只能import導入 --save 支持異步
// @ts-ignore
// import fetch from 'node-fetch'; //不能在模塊之外使用
// fetch(url)
// .then(res => res.json()) // expecting a json response
// .then(json => {
// console.log(json);
// })
// .catch(err => {
// console.log(err);
// });
var p1 = new Promise(function (resolve, reject) {
resolve('p1 resolve');
});
var p2 = new Promise(function (resolve, reject) {
resolve('p2 resolve');
});
//只要p1,p2中的其中一個有狀態(tài)改變,馬上返回pRace
var pRace = Promise.race([p1, p2]);//將多個Promise生成一個Promise
pRace.then(function (value) {
console.log(value);
});typescript- typescrip與react
對象的類型
接口 Interfaces 一般首字母大寫
interface Person {
? ? readonly id: number; // 只讀屬性 不能修改
? ? name: string;
? ? age: number;
? ? age?: number; ? // 可選
? ? [propName: string]: any; // 任意屬性
? ? // 注意,
}
// 順序 一般是 只讀 -> 默認 -> 可選 -> 任意
let tom: Person = {
? ? name: 'Tom',
? ? age: 25
};一旦定義了任意屬性,那么確定屬性和可選屬性的類型都必須是它的類型的子集:
interface Person {
? ? name: string;
? ? age?: number;
? ? [propName: string]: string;
}
let tom: Person = {
? ? name: 'Tom',
? ? age: 25, ? ? // 報錯 需要是 任意屬性的子集
? ? gender: 'male'
};任意屬性的值允許是 string,但是可選屬性 age 的值卻是 number,number 不是 string 的子屬性,所以報錯了
只讀的約束存在于第一次給對象賦值的時候,而不是第一次給只讀屬性賦值的時候
interface Person {
? ? readonly id: number;
? ? name: string;
? ? age?: number;
? ? [propName: string]: any;
}
let tom: Person = {
? ? name: 'Tom',
? ? gender: 'male'
};
tom.id = 89757; ? // 報錯,第一處是在對 tom 進行賦值的時候,沒有給 id 賦值。 之后再賦值就報錯數組類型
「類型 + 方括號」表示法
let arr: number[] = [1, 2, 3, 4, 5]; // 表示 是數組, 并且數組元素只能為 number 類型
聯(lián)合類型和數組的結合
// arr 表示 是數組, 并且數組元素只能為 number 和 string 類型 let arr: (number | string)[] = ['1', 'adaf', 2, 3, 5]
數組泛型
let arr: Array<number> = [1, 2, 3, 4, 5];
類數組
常見的類數組都有自己的接口定義,如 IArguments, NodeList, HTMLCollection 等
// error 函數中的 arguments 這也定義會報錯 let args: number[] = arguments; // success 改成 let args: IArguments = arguments;
函數類型
函數聲明
function sum(x: number, y: number): number {
? ? return x + y;
}函數表達式
let mySum = function (x: number, y: number): number {
? ? return x + y;
};這是可以通過編譯的,不過事實上,上面的代碼只對等號右側的匿名函數進行了類型定義,而等號左邊的 mySum,是通過賦值操作進行類型推論而推斷出來的。如果需要我們手動給 mySum 添加類型,則應該是這樣:
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
? ? return x + y;
};類型斷言
function getLength(something: string | number): number {
? ? // 將他斷言為 string
? ? if ((<string>something).length) {
? ? ? ? return (<string>something).length;
? ? } else {
? ? ? ? return something.toString().length;
? ? }
}類型斷言不是類型轉換,斷言成一個聯(lián)合類型中不存在的類型是不允許的:
// error?
function toBoolean(something: string | number): boolean {
? ? return <boolean>something;
}
// Type 'number' is not comparable to type 'boolean'內置對象
ECMAScript 的內置對象
Boolean、Error、Date、RegExp 等。
DOM 和 BOM 的內置對象
Document、HTMLElement、Event、NodeList 等。
泛型
是指在定義函數、接口或類的時候,不預先指定具體的類型,而在使用的時候再指定類型的一種特性。
function swap<T, U>(tuple: [T, U]): [U, T] {
? ? return [tuple[1], tuple[0]];
}問題
type 和 Interfaces 的區(qū)別
React 中使用
import React, { MouseEvent, ReactNode } from 'react'
type Props = {?
?onClick(e: MouseEvent<HTMLElement>): void
?children?: ReactNode?
}
const Button = ({ onClick: handleClick, children }: Props) => (
? <button onClick={handleClick}>{children}</button>
)高階組件的使用方式
import React from 'react';
import { Form } from 'antd';
import { FormComponentProps } from 'antd/es/form';
interface IProps extends FormComponentProps {
? loading: boolean;
}
const Page: React.FC<IProps> ?= (props) => {
? return (
? ? ?<div>Page</div>
? )
}
export default Form.create<IProps>()(Page)對象類型取值
type DealWithProps = {
? onClose: Function;
? eventId: string;
? dealTime: any;
};
// 處理
const getOnDealWith = (parameObj: DealWithProps) => () => {
? // TODO 暫無接口
? for (let i in parameObj) {
? ? console.log(parameObj[i], typeof parameObj[i]);
? ? ? // 報錯?
? ? ? /**
? ? ? Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'DealWithProps'.
? No index signature with a parameter of type 'string' was found on type 'DealWithProps'.ts(7053)
? ? ? **/
? }
};Event 事件對象類型
常用 Event 事件對象類型:
ClipboardEvent<T = Element>剪貼板事件對象DragEvent<T = Element>拖拽事件對象ChangeEvent<T = Element>Change 事件對象KeyboardEvent<T = Element>鍵盤事件對象MouseEvent<T = Element>鼠標事件對象TouchEvent<T = Element>觸摸事件對象WheelEvent<T = Element>滾輪事件對象AnimationEvent<T = Element>動畫事件對象TransitionEvent<T = Element>過渡事件對象
Promise 類型
Promise<T> 是一個泛型類型,T 泛型變量用于確定使用 then 方法時接收的第一個回調函數(onfulfilled)的參數類型。
interface IResponse<T> {
? message: string,
? result: T,
? success: boolean,
}
async function getResponse (): Promise<IResponse<number[]>> {
? return {
? ? message: '獲取成功',
? ? result: [1, 2, 3],
? ? success: true,
? }
}
getResponse()
? .then(response => {
? ? console.log(response.result)
? })使用 react-router-dom
withRouter(ModuleLayout)
這類高階組件的使用 方式,通常都需要繼承到高階組件 的 類型定義,如 antd Form.create 需要繼承 FormComponentProps
import { FormComponentProps} from 'antd/lib/form/Form';
import { withRouter, Link, RouteComponentProps } from 'react-router-dom';
interface IProps extends RouteComponentProps<any> {
? basePath: string;
? menuList: IMenuItem[];
? children: JSX.Element;
}
function App(props: IProps){
? ? // 因為繼承了 RouteComponentProps 所以可以獲取 location
? ? const {location} = props;
? ? // xx
}
export default withRouter(ModuleLayout);react 定義方法 useApi
/* eslint-disable no-param-reassign */
import { useRef, useEffect } from '@alipay/bigfish/react';
import { useImmer } from 'use-immer';
type Service<T> = () => Promise<T>;
type DependencyList = ReadonlyArray<any>;
interface Option<T> {
? onSuccess?: (data: T) => void;
? onError?: (errMsg: string) => void;
}
interface State {
? data: any;
? loading: boolean;
}
interface ResponseData<T> {
? success: boolean;
? data: T;
? message: string;
}
export default function useApi<T>(
? service: Service<ResponseData<T>>,
? dependencyList: DependencyList = [],
? option?: Option<T>
) {
? const initialState: State = {
? ? data: undefined,
? ? loading: false,
? };
? const [state, setState] = useImmer(initialState);
? const serviceId = useRef(0);
? useEffect(() => {
? ? const currentId = serviceId.current;
? ? setState(draft => {
? ? ? draft.loading = true;
? ? ? draft.data = null;
? ? });
? ? // 異步方法
? ? service().then(data => {
? ? ? // 組件卸載不更改
? ? ? if (currentId !== serviceId.current) {
? ? ? ? return;
? ? ? }
? ? ? if (!data.success) {
? ? ? ? // 錯誤
? ? ? ? setState(draft => {
? ? ? ? ? draft.loading = false;
? ? ? ? ? draft.data = null;
? ? ? ? });
? ? ? ? if (option && option.onError) {
? ? ? ? ? option.onError(data.message);
? ? ? ? }
? ? ? } else {
? ? ? ? // 成功
? ? ? ? setState(draft => {
? ? ? ? ? draft.loading = false;
? ? ? ? ? draft.data = data.data;
? ? ? ? });
? ? ? ? if (option && option.onSuccess) {
? ? ? ? ? option.onSuccess(data.data);
? ? ? ? }
? ? ? }
? ? });
? ? return () => {
? ? ? serviceId.current += 1;
? ? };
? }, dependencyList);
? return [state, setState];
}react 使用 useRef
import React, { useRef, useState, FC } from '@alipay/bigfish/react';
import { message } from 'antd';
interface IProps extends FormComponentProps {
? isShow:boolean;
}
interface IUseRef extends HTMLDivElement {
? getAssets: Function;
}
const CreateStep: FC<IProps> = props => {
? const {
? ? form, isShow
? } = props;
? const refList = useRef<IUseRef>(null);
? const [current, setCurrent] = useState(1);
? function setNextStep() {
? ? const { current } = refList;
? ? const { getAssets } = current; // 類型“IUseRef | null”上不存在屬性“getAssets”
? }
? return <div ref={refList}>xxxx</div>;
};
export default CreateStep;上面定義泛型的時候, 這個寫法會報一個錯誤,因為 current 開始會是空的,后面 dom 掛在之后才會獲取實例。
看下 useRef 源碼定義, 也就是泛型的值就是 current 的結果
interface RefObject<T> {
? ?readonly current: T | null;
}
function useRef<T>(initialValue: T|null): RefObject<T>;并且 ref={ refLise } 需要傳入的是 dom 元素節(jié)點,所以通過繼承 HTMLDivElement 來得到 useRef 泛型。
interface IUseRef extends HTMLDivElement {
getAssets: Function;
}所以解決的方法。
方法一: 類型斷言, 但是這樣的代碼其實是不嚴警的
?const { getAssets } = current as IUseRef;方法二: 通過 if 判斷,消除 current 為 null 的時候,如果不為 null 這里的類型就必定是 IUseRef 類型,所以可以取出 getAssets
let getAssets ;
if(current && current.getAssets){
? getAssets = current.getAssets;
}以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
使用JavaScript和MQTT開發(fā)物聯(lián)網應用示例解析
這篇文章主要介紹了使用JavaScript和MQTT開發(fā)物聯(lián)網應用示例解析,文章通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
mint-ui的search組件在鍵盤顯示搜索按鈕的實現(xiàn)方法
這篇文章主要介紹了mint-ui的search組件在鍵盤顯示搜索按鈕的實現(xiàn)方法,需要的朋友可以參考下2017-10-10
Electron autoUpdater實現(xiàn)Windows安裝包自動更新的方法
這篇文章主要介紹了Electron autoUpdater實現(xiàn)Windows安裝包自動更新的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
js將table的每個td的內容自動賦值給其title屬性的方法
下面小編就為大家?guī)硪黄猨s將table的每個td的內容自動賦值給其title屬性的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10
完美解決input[type=number]無法顯示非數字字符的問題
下面小編就為大家?guī)硪黄昝澜鉀Qinput[type=number]無法顯示非數字字符的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02

