async函数是什么,async的用法

http://www.itjxue.com  2023-01-06 20:35  来源:未知  点击次数: 

js函数前面加async是什么意思

async表示异步的意思,如果前面加上 async =false 就表示同步的方式运行,当程序读到这句话的要等到它运行完毕之后才执行下面的程序。

而如果是 async =true ; 就表示异步的方式运行,不用等到当前语句返回结果就会继续下面的语句。这样运行更流畅,不会出现停顿的现象。

ES6 之 async 异步函数

1、什么是 async 函数?

异步读取两个文件,用 Generator 函数的写法

异步读取两个文件,用 async 函数的写法

一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。

2、async函数对 Generator函数的改进,体现在哪些方面?

3、async 函数的基本用法

async 函数有多种使用形式。

4、async 语法

5、async函数的实现原理

6、实例:按顺序完成异步操作

7、异步遍历器

for...of循环用于遍历同步的 Iterator 接口。新引入的 for await...of 循环,则是用于遍历异步的 Iterator 接口。

8、异步 Generator 函数

在语法上,异步 Generator 函数就是async函数与 Generator 函数的结合。

异步遍历器的设计目的之一,就是 Generator 函数处理同步操作和异步操作时,能够使用同一套接口。

yield* 语句也可以跟一个异步遍历器。

与同步 Generator 函数一样,for await...of循环会展开yield*。

参考链接 : 阮一峰ES6教程

js async和await的用法

async 是一个修饰符,被它定义的函数会默认的 返回 一个 Promise 的 resolve的值。

因此对 async 函数可以直接进行 then 操作,返回的值即为 then() 方法的传入函数。

await 同 async 一样,作为修饰符,但是它只能放在 async 内部使用。

它是 获取 Promise 中返回的内容, 即这个 Promise 函数中 resolve 或者 reject 的值。

所以,async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。

如下例:

比如说,这样一个场景:等待三个数据结果都返回,计算它们的和

JS异步操作新体验之 async函数

文章来自

async 函数返回一个 Promise 实例对象,可以使用 then 方法添加回调函数。

当函数执行时,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句

(1)、async 函数内部 return语句返回的值,会成为then方法回调函数的参数

(2)、async 函数内部抛出错误,会导致返回的 Promise对象变成reject状态,抛出的错误会被catch方法回调函数接收到

(3)、只有 async 函数内部的异步操作执行完,才会执行 then方法指定的回调函数

实际应用

async函数的基本用法

1. async函数的基本形式

//函数声明asyncfunction foo() {}//函数表达式const foo = asyncfunction () {};//对象的方法let obj = { async foo() {} };

obj.foo().then(...)//Class 的方法class Storage {

constructor() {

? ? this.cachePromise = caches.open('avatars');

}

async getAvatar(name) {

? ? const cache = awaitthis.cachePromise;

? ? returncache.match(`/avatars/${name}.jpg`);

}

}

const storage =new Storage();

storage.getAvatar('jake').then(…);//箭头函数const foo = async () = {};

2. async函数的返回值总是一个Promise

无论async函数有无await操作,其总是返回一个Promise。

1. 没有显式return,相当于return Promise.resolve(undefined);

2. return非Promise的数据data,相当于return Promise.resolve(data);

3. return Promise, 会得到Promise对象本身

async总是返回Promise,因此,其后面可以直接调用then方法,

函数内部return返回的值,会成为then回调函数的参数

函数内部抛出的错误,会被then的第二个函数或catch方法捕获到

//正常返回值asyncfunction f(){

? ? retrun 'hello world';

}

f().then(v = console.log(v));//hello world//抛出错误asyncfunction f(){

? ? thrownewError('出错了');

}

f().then(

? ? v = console.log(v),

? ? e = console.log(e)//Error: 出错了)

3. await操作符的值

[rv] = await expression(expression可以是任何值,通常是一个promise)

expression是Promise,rv等于Promise兑现的值,若Promise被拒绝,则抛出异常,由catch捕获

expression是非Promise,会被转换为立即resolve的Promise,rv等于expression

await操作只能用在async函数中,否则会报错。

4. async就是generator和promise的语法糖

//generator写法vargen =function* () {

? varf1 = yield readFile('/etc/fstab');

? varf2 = yield readFile('/etc/shells');

? console.log(f1.toString());

? console.log(f2.toString());

};//async写法varasyncReadFile = asyncfunction () {

? varf1 = await readFile('/etc/fstab');

? varf2 = await readFile('/etc/shells');

? console.log(f1.toString());

? console.log(f2.toString());

};

async就是将 generator的 * 换成 async,将 yield 换成 await。

5. async对generator的改进

1. 内置执行器

Generator必须依靠执行器调用next方法来自动执行,例如co模块。而async函数自带执行器,可以自动执行。

2. 更好的语义

async和await分别表示异步和等待,语义更加明确

3. 适用性更强

co模块后面只能是Thunk函数或Promise对象,而await后面可以是Promise或基本数据类型(如:数字,字符串,布尔等)

4. 返回Promise,可以继续操作

async函数总是返回一个Promise对象,可以对其进行then调用,继续操作后面的数据,因此,

async函数完全可以看作是多个Promise合成一个Promise对象,而await命令就是内部的then调用。

6. async内部的并行调用

async配合await都是串行调用,但是若有并行调用,则应按照以下方式来写:

1. 变量分别接收Promise

let fooPromise = getFoo();

let barPromise = getBar();

let foo = await fooPromise();

let bar = await barPromise();

2. 使用Promise.all

let [foo,bar] = await Promise.all([getFoo(),getBar()]);

Promise.all这种写法有缺陷,一个调用报错,会终止,这个不太符合并行调用的初衷。

3. 使用多个async函数

实际上,一个async函数内部包含的调用应该是强相关的,没有依赖关系的函数调用不应该放在一个async函数中,分开来逻辑更清晰。

4. 并行执行的一些写法

1. 不能再内部非async function中使用await

asyncfunction dbFuc(db) {

? let docs = [{}, {}, {}];

? // 报错,forEach的function是非async,不能使用awaitdocs.forEach(function (doc) {

? ? await db.post(doc);

? });

}//这里不需要 asyncfunction dbFuc(db) {

? let docs = [{}, {}, {}];

? // 可能得到错误结果,这样调用也不能得到正确的结果docs.forEach(asyncfunction (doc) {

? ? await db.post(doc);

? });

}

2. 循环调用await可以使用for循环或for of循环

//for ofasyncfunction dbFuc(db) {

? let docs = [{}, {}, {}];

? for (let doc of docs) {

? ? await db.post(doc);

? }

}//map + Promise.allasyncfunction dbFuc(db) {

? let docs = [{}, {}, {}];

? let promises = docs.map((doc) = db.post(doc));

? let results = await Promise.all(promises);

? console.log(results);

}//map + for ofasyncfunction dbFuc(db) {

? let docs = [{}, {}, {}];

? let promises = docs.map((doc) = db.post(doc));

? let results = [];

? for (let promise of promises) {

? ? results.push(await promise);

? }

? console.log(results);

}//for循环中去请求网页,若await操作成功,会break退出;若失败,会catch捕获,进入下一轮循环const superagent = require('superagent');

const NUM_RETRIES = 3;

async function test() {

? let i;

? for(i = 0; i NUM_RETRIES; ++i) {

? ? try {

? ? ? await superagent.get('');

? ? ? break;

? ? } catch(err) {}

? }

? console.log(i); // 3}

test();

7. async的错误处理

使用try...catch进行包裹,例如:

asyncfunction myFunction() {

? ? try {

? ? ? ? await somethingThatReturnsAPromise();

? ? } catch (err) {

? ? ? ? console.log(err);

? ? }

}

如果仅仅对一部分错误进行处理或者忽略,可以局部的进行包裹,或者对单独的promise进行catch,例如:

asyncfunction myFunction() {

? ? await somethingThatReturnsAPromise().catch((err)= {

? ? ? ? ? ? console.log(err);

? ? })

}

async function myFunction() {

? ? try{

? ? ? ? await somethingThatReturnsAPromise();

? ? }

? ? catch(e){}

? ? await somethingElse();

}

Promise的错误处理,推荐用async + await来写:

// 存值createData(title, successBack, errorBack) {

? ? // 使用key保存数据? ? storage.save({

? ? ? ? key: title,?

? ? ? ? data: 'true',

? ? }).then(successBack(), errorBack());

}

改写为

//存值async createData1(title, successBack, errorBack) {

? ? try {

? ? ? ? // 使用key保存数据? ? ? ? await storage.save({

? ? ? ? ? ? key: title,?

? ? ? ? ? ? data: 'true',

? ? ? ? });

? ? ? ? successBack()

? ? } catch (e) {

? ? ? ? errorBack()

? ? }

}

形式上更加清晰一些。

8. async函数的实现原理

async函数就是将执行器和Generator做为一个整体返回。

asyncfunction fn(){}//等同于function fn(){

? ? returnspawn(function* (){

? ? })

}

spawn的实现

function spawn(genF) {

? ? /****

? ? * 返回的是一个promise

? ? */returnnewPromise(function(resolve, reject) {

? ? ? ? vargen=genF();//运行Generator这个方法;/***

? ? ? ? * 执行下一步的方法

? ? ? ? * @param fn 一个调用Generator方法的next方法

? ? ? ? */function step(fn) {

? ? ? ? ? ? //如果有错误,则直接返回,不执行下面的awaittry {

? ? ? ? ? ? varnext=fn();

? ? ? ? ? ? }catch (e){

? ? ? ? ? ? return reject(e)

? ? ? ? ? ? }

? ? ? ? ? ? //如果下面没有yield语句,即Generator的done是trueif(next.done){

? ? ? ? ? ? return resolve(next.value);

? ? ? ? ? ? }

? ? ? ? ? ? Promise.resolve(next.value).then((val)={

? ? ? ? ? ? ? ? step(function(){return gen.next(val) } )

? ? ? ? ? ? }).catch((e)={

? ? ? ? ? ? ? ? step(function(){returngen.throw(e) } )

? ? ? ? ? ? })

? ? ? ? }

? ? ? ? step(function () {

? ? ? ? ? ? return gen.next();

? ? ? ? })

? ? });

}

参考自 async的基本用法 - 看风景就 - 博客园

(责任编辑:IT教学网)

更多

推荐网络创业文章