关于async-await:async异步工具

在es6中的async的语法中,能够参照java并发包实现一些有意思的异步工具,辅助在异步场景(个别指申请)下的开发。因为js是单线程,上面的实现都比java中实现简略 (抛除线程概念)。同时波及到js的执行机制,宏工作,微工作,async,promise相干内容,须要提前具备这些常识。 wait(期待)异步函数中,期待(相当于java线程中的阻塞)一段时间。 实现代码: async function wait(time = 0) { await new Promise(resolve => setTimeout(resolve, time)); // 防止转译成return await, 会在一些safari版本外面报错 return undefined;}模仿应用代码: (async () => { console.time(); await wait(1000); console.timeEnd(); // 输入: default: 1.002s})();Lock(锁)模仿java并发包中的Lock类实现锁操作。 保障同一个锁突围的异步代码执行过程中,同一时刻只有一段代码在执行。 该锁不合乎html5的的异步锁接口,而是提供一个java异步包中Lock接口的简略实现举荐应用场景:多个申请执行过程前,保障同一时刻只有一个token生效验证转换操作。 实现代码: export type Resolve<T = any> = (value: T | PromiseLike<T>) => void;export type Reject = (reason?: any) => void;export interface FlatPromise<T = any> { promise: Promise<T>; resolve: Resolve<T>; reject: Reject;};interface Key { key: number, resolve: Resolve,};/*** 创立一个扁平的promise* @returns Prmise*/function flatPromise<T = any>(): FlatPromise<T> { const result: any = {}; const promise = new Promise<T>((resolve, reject) => { result.resolve = resolve; result.reject = reject; }); result.promise = promise; return result as FlatPromise<T>;}class Lock { keys: Key[] = []; hasLock: boolean = false; idCount: number = 0; constructor() { this.keys = []; this.hasLock = false; this.idCount = 0; } _pushKey(resolve: Resolve) { this.idCount += 1; const key: Key = { key: this.idCount, resolve, }; this.keys.push(key); return key; } _removeKey(key: Key) { const index = this.keys.findIndex(item => item.key === key.key); if (index >= 0) { this.keys.splice(index, 1); } } /** * 获取锁. * 如果以后锁曾经锁定,那么就阻塞以后操作 */ async lock() { if (this.keys.length || this.hasLock) { const { promise, resolve } = flatPromise(); this._pushKey(resolve); await promise; return null; } this.hasLock = true; return null; } /** * 尝试获取锁. * 该函数如果没有指定一个无效的time,则立马返回一个后果:如果获取到锁则为true,反之为false. * 如果指定一个无效的time(time=0无效),则返回一个promise对象,改对象返回的后果为是否获取到锁 * @param time 最长等待时间 */ tryLock(time?: number) { if (time === undefined || Number.isNaN(Math.floor(time)) || time < 0) { if (this.hasLock) { return false; } this.lock(); return Promise.resolve(true); } if (!this.hasLock && !this.keys.length) { this.hasLock = true; return Promise.resolve(true); } const asyncFn = async () => { const { promise, resolve: res } = flatPromise(); const key = this._pushKey(res); setTimeout(() => { this._removeKey(key); key.resolve(false); }, time); const isTimeout = await promise; return isTimeout !== false; }; return asyncFn(); } async lockFn(asyncFn: () => Promise<void>) { await this.lock(); try { await asyncFn(); } finally { this.unlock(); } } /** * 开释锁 */ unlock() { if (this.keys.length === 0 && this.hasLock === true) { this.hasLock = false; return; } if (this.keys.length === 0) { return; } const index = Math.floor(Math.random() * this.keys.length); const key = this.keys[index]; this._removeKey(key); key.resolve(undefined); } toString() { return `${this.keys.length}-${this.hasLock}`; }}模仿应用代码: ...

June 18, 2022 · 4 min · jiezi

关于async-await:vue项目asyncawait封装axios请求

装置axiosnpm install axios --save 创立http.js文件import axios from "axios"/* 申请拦截器 */axios.interceptors.request.use( config => { /* 增加token */ let token = localstorage.getItem("token") || ""; if(token){ config.headers["token"] = token } return config; }, error => { return Promise.reject(error) })export const http = (url,params,method='GET',type='json') =>{ /* 设置工夫随机数,解决申请缓存问题 */ let _t = new Date().getTime(); if(method == 'GET' || method == 'get'){ if(params){ params._t = _t }else{ params={ _t } } } /* 设置申请头 */ if (method === "POST") { if (type == "json") { //参数是json类型 axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8"; } else { //参数是字符串类型 axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; // params = Qs.stringify(params); } } /* 发送申请 */ return new Promise((resolve,reject) => { axios({ url, method, type, data:method != "GET" ? params : null, params:method == "GET" ? params : null }) .then(result => { /* 此处能够全局解决接口非凡状态码,比方token生效等 */ resolve(result.data) }) .catch(error => { reject(error) }) })}/* await to js */export const to = promise => { return promise.then(res => [null,res]).catch(error => [error])}创立api.js文件,设置接口申请解决import { http, to } from "./http";// ---- 全局接口 -----export const ceshiList = params => { return to(http("json/ceshi.json", params, "GET"));};api应用import { ceshiList } from "@/http/api.js";methods:{ async getList(){ let [err, res] = await ceshiList(); if (!err) { if (res.result.code == 200) { /* 接口申请正确处理 */ console.log(res); } } }}转化blob返回的数据const render = new FileReader();render.onload = function(){ let jsonData = JSON.parse(render.result)}render.readAsText(data)

December 20, 2021 · 1 min · jiezi

关于async-await:asyncawait-使用方式

先说一下async的用法,它作为一个关键字放到函数后面,用于示意函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞前面代码的执行。 写一个async 函数 async function timeout() { return 'hello world';}语法很简略,就是在函数后面加上async 关键字,来示意它是异步的,那怎么调用呢?async 函数也是函数,平时咱们怎么应用函数就怎么应用它,间接加括号调用就能够了,为了示意它没有阻塞它前面代码的执行,咱们在async 函数调用之后加一句console.log; async function timeout() { return 'hello world'}timeout();console.log('尽管在前面,然而我先执行');关上浏览器控制台,咱们看到了async 函数 timeout 调用了,然而没有任何输入,它不是应该返回 'hello world', 先不要焦急, 看一看timeout()执行返回了什么? 把下面的 timeout() 语句改为console.log(timeout()) async function timeout() { return 'hello world'}console.log(timeout());console.log('尽管在前面,然而我先执行');持续看控制台原来async 函数返回的是一个promise 对象,如果要获取到promise 返回值,咱们应该用then 办法, 持续批改代码 async function timeout() { return 'hello world'}timeout().then(result => { console.log(result);})console.log('尽管在前面,然而我先执行');看控制台 咱们获取到了"hello world', 同时timeout的执行也没有阻塞前面代码的执行,和咱们方才说的统一。 这时,你可能留神到控制台中的Promise 有一个resolved,这是async 函数外部的实现原理。如果async 函数中有返回一个值 ,当调用该函数时,外部会调用Promise.solve() 办法把它转化成一个promise 对象作为返回,但如果timeout 函数外部抛出谬误呢? 那么就会调用Promise.reject() 返回一个promise 对象, 这时批改一下timeout 函数 ...

August 30, 2021 · 3 min · jiezi

关于async-await:ES6新增语法七asyncawait

什么是asyncasync的意思是“异步”,顾名思义就是无关异步操作的关键字,async 是 ES7 才有的,与咱们之前说的Promise、Generator有很大的关联。 应用语法: async function name(param){ param //传递给函数的参数名称 statements //函数体 } name().then(function(res){ res//异步操作返回的后果 }) async 函数返回一个Promise对象,能够应用then办法增加回调函数。具体实例如下: async function show(){ return {a:12,b:15}}console.log(show())//Promise {<fulfilled>: {…}}show().then(res=>{ console.log("res",res)})什么是awaitawait关键字存在async函数表达式中,用于期待Promise对象,暂停执行,等到异步操作实现后,复原async函数的执行并返回解析值。如果把await放在asnyc函数体外,会报语法错误。 应用语法: asnyc function name(){ returnValue = await expression; } expression 是一个Promise对象或一个须要期待的值,针对所跟不同表达式,有两种解决形式: 对于Promise对象,await会阻塞主函数执行,期待Promise对象执行resolve之后,resolve返回值作为await表达式运算后果,而后持续向下执行。 对于非Promise对象,能够是字符串、布尔值、数值以及一般函数等。await间接返回对应的值,而不是期待其执行后果。 await期待Promise对象实例如下: async function test1(){ console.log("执行") return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log("提早3秒之后返回胜利") resolve({a:'1'}) },3000) }) }async function test2(){ let x = await test1() console.log("x",x)//{a: "1"} return x}test2().then(function(res){ console.log("res",res)//{a: "1"}})await 跟 一般函数 实例如下: ...

July 22, 2021 · 1 min · jiezi

关于async-await:asyncawait是如何捕获异常的

function 猜大小(猜想) { return new Promise((resolve, reject) => { // 背下来 console.log("开始摇色子"); setTimeout(() => { let n = 6; //parseInt(Math.random() * 6 + 1, 10); // 1~6 if (n > 3) { if (猜想 === "大") { resolve(n); } else { reject(n); } } else { if (猜想 === "小") { resolve(n); } else { reject(n); } } }, 1000); });}async function test() { try { let n /*[6,6]*/ = await Promise.all([猜大小("大"), 猜大小("大")]); console.log("好嗨哦" + n); } catch (error) { console.log("输光了" + error); }}var result = test();console.log(result);

January 16, 2021 · 1 min · jiezi

关于async-await:async和await原理

generatorasync和await是generator的语法糖,想要搞清楚async和await必须晓得generator;那么咱们先来看看generator函数; function * getAge() { yield 1; yield 2;}let gen = getAge();console.log(gen.next());//{ value: 1, done: false }console.log(gen.next());//{ value: 2, done: false }console.log(gen.next());//{ value: undefined, done: true }generator和一般函数的区别: 1.generator申明函数之前要加* 2.函数中有yield,能够管制函数的运行 generator传参问题function * getAge() { let a = yield 1; console.log(a);//444 yield 2;}let gen = getAge();console.log(gen.next());console.log(gen.next(444));generator传参能够将参数传在next函数中,给a赋值,然而第一个next()函数永远是undefined;如下 function * getAge(xxx) { let a = yield 1; console.log(a);//undefined yield 2;}let gen = getAge();console.log(gen.next(444));console.log(gen.next());generator函数运行过程 generator实现读取异步函数当初有一个name和age的txt文件,咱们通过name.txt读取age.txt里的内容;我这里的name中写的是age.txt,age.txt中写的是18; let {promisify} = require('util');let fs = require('fs');let read = promisify(fs.readFile);function * getAge() { let name = yield read(`${__dirname}name.txt`, 'utf-8'); let age = yield read(`${__dirname}${name}`, 'utf-8');}let it = getAge();let {value} = it.next();//返回的是读取name.txt的promise函数value.then(data => { let {value} = it.next(data)//将读取name文件的内容作为参数赋值给getAge函数中的name,同时这里的value是读取age.txt的promise函数 value.then(data => { console.log(data)//18 })});async和await下面层层嵌套看着很乱尤其是嵌套多的状况下,那么咱们应用async和await实现一下这里只是将generator函数中的*换成了async,将yield换成了await ...

November 18, 2020 · 2 min · jiezi