async属不属于es6属性


本篇内容介绍了“async属不属于es6属性”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 属于,async是es6的新特性,用于表明程序里面可能有异步过程。用async关键字声明的函数返回的是一个Promise对象,如果在函数中return一个直接量,async会把这个直接量通过Promise.resolve()封装成Promise对象;当async函数没有返回值时,返回“Promise.resolve(undefined)”。我们先从字面意思来理解这两个关键字,async是asynchronous(异步)的简写,而await可以认为是async wait的简写。所以async可以理解为用于声明一个函数是异步的,而await用于等待一个异步任务执行完成。async和await关键字让我们可以用一种更简洁的方式写出基于promise的异步行为,而无需刻意地链式调用promise。接下来我们通过先几个例子,初步了解一下async和await的作用。知识点1: 用 async 关键字声明的函数返回的是一个 Promise 对象。如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。当 async 函数没有返回值时,返回 Promise.resolve(undefined)

//定义一个普通函数,返回一个字符串
functiontest(){
return"helloasync";
}
constresult1=test();
console.log(result1);//输出一个字符串helloasync

//定义一个使用了async修饰的函数,同样返回一个字符串
asyncfunctiontestAsync(){
return"helloasync";
}
constresult2=testAsync();
console.log(result2);//输出一个Promise对象Promise{:'helloasync'}

//async较好的用法
asyncfunctiontestAsync(){
//返回一个Promise对象
returnnewPromise((resolve,reject)=>{
//处理异步任务
setTimeout(function(){
resolve("testAsync")
},1000);
})
}
//async通常用于声明一个处理异步任务且返回了Promise对象的函数

知识点2: await关键字只能使用在被async声明的函数内,用于修饰一个Promise对象,使得该Promise对象处理的异步任务在当前协程上按顺序同步执行。

//定义一个使用async修饰的函数,处理异步任务
asyncfunctiontestAsync(){
returnnewPromise((resolve,reject)=>{
setTimeout(function(){
resolve("testAsync")
},1000);
})
}

//定义一个函数,直接调用testAsync函数
functiontestAwait(){
console.log('testAsync调用前')
testAsync().then(res=>{
console.log(res)//输出"testAsync"
})
console.log('testAsync调用后')
}

/*****输出如下*****/
testAsync调用前
testAsync调用后
testAsync
//尽管代码按顺序写,但不按顺序执行,因为testAsync()是异步函数

//定义一个函数(不使用async声明该函数)用await修饰调用testAsync函数
functiontestAwait(){
console.log('testAsync调用前')
awaittestAsync().then(res=>{//使用await关键字修饰
console.log(res)
})
console.log('testAsync调用后')
}

//调用testAwait()函数
testAwait()
//报错:UncaughtSyntaxError:awaitisonlyvalidinasyncfunctionsandthetoplevelbodiesofmodules,因为await只能使用在被async修饰的函数内。

//定义一个函数(使用async声明该函数)用await修饰调用testAsync函数
asyncfunctiontestAwait(){
console.log('testAsync调用前')
awaittest免费云主机域名Async().then(res=>{
console.log(res)
})
console.log('testAsync调用后')
}

/*****输出如下*****/
testAsync调用前
testAsync
testAsync调用后

//使用了await关键字修饰,使得代码按照顺序执行,即同步执行

(1)用于表明程序里面可能有异步过程(2)async函数返回值的类型为Promise对象: 这是和普通函数本质上不同的地方,也是使用时重点注意的地方;return newPromise( ),这个用法符合async函数本意;return data,特别注意到是这样子写相当于Promise.resolve(data),返回的data被封装成一个Promise对象,但是在调用async函数的地方通过简单的=是拿不到这个返回值data的,因为返回值是一个Promise对象,所以需要用.then(data => { })方式才可以拿到这个data;如果没有返回值,相当于返回了Promise.resolve(undefined);(3)无等待,非阻塞:使用async关键字声明的函数里面如果有异步过程可能会等待,但是函数本身会马上返回,不会阻塞当前主线程。如果在函数里面使用了await关键字修饰的异步过程,其工作在相应的协程上,会阻塞等待异步任务的完成再返回。

//定义一个函数,处理异步任务(使用定时器模拟),返回一个Promise对象
asyncfunctiontestAsync(){
returnnewPromise((resolve,reject)=>{
setTimeout(function(){
resolve("成功调用testAsync")
},1000);
});
}

//定义一个函数,使用await关键字修饰调用testAsync()函数
asyncfunctiontestAwait(){
//使用了await关键字修饰调用testAsyn()函数
awaitthis.testAsync().then(res=>{
console.log(res)//输出的是testAsync()函数resolve的值
});
console.log("helloAsync");
}

//主线程
console.log('testAwait调用前')
testAwait();
console.log('testAwait调用后')

/*****输出结果如下*****/
testAwait调用前
testAwait调用后//因为testAwait()函数使用了async关键字修饰,所以不会阻塞主线程的执行,所以这两句话会先直接输出,然后再执行testAwait()函数
成功调用testAsync//因为testAwait()函数在内部调用testAsync()函数时使用了await关键字修饰,所以在对应的协程上会阻塞,等待testAsync()函数执行完,再输出下面那句'helloAsync'
helloAsync

(1)await只能在async函数内部使用:不能放在普通函数里面,否则会报错。(2)await关键字后面跟的是一个Promise对象。如果跟的是一个函数,则这个函数应当返回一个Promise对象。如果跟的是非Promise对象,则会通过Promise.resolve( )函数自动将这个东西包装成一个Promise对象并置于fulfilled状态。

//例如:
consta=await'HelloAwait'
//相当于
consta=awaitPromise.resolve('HelloAwait');

console.log(a)//输出'HelloAwait'

(3)await的本质是等待它所修饰的Promise对象的fulfilled状态,并把resolve(data)的数据data返回。

(3)await的本质是等待它所修饰的Promise对象的fulfilled状态,并把resolve(data)的数据data返回。
意思是,如果await后面跟的是一个 Promise 对象,await 就会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

asyncfunctiontestAsync(){
returnnewPromise((resolve,reject)=>{
setTimeout(function(){
resolve("成功调用testAsync")
},1000);
});
}

consta=awaittestAsync()//这里的a就会拿到testAsync函数resolve的数据
console.log(a)//在一秒后输出'成功调用testAsync'

(4)await并不关心它所修饰的Promise对象的rejected状态,即reject(data)的数据data并不会被await处理,所以建议通过Promise对象调用catch去捕获。

asynctestAwait(){
//变量a用于接收testAsync()函数resolve的数据
leta=awaittestAsync().catch(err=>{
//处理异常和reject的数据
})
}

(1)执行顺序

//定义一个函数,该函数接收一个参数,1s后再返回参数的两倍
asyncfunctiondouble(num){
returnnewPromise((resolve,reject)=>{
setTimeout(()=>{//使用定时器模拟异步任务
resolve(2*num)//将运算结果交给resolve
},1000);
})
}

asyncfunctiongetResult(){
console.log('double调用前')//顺序:2
letresult=awaitdouble(10);//将10作为参数传递给double函数
//result变量用于接收double()函数resolve的值
console.log(result);//顺序:4
console.log('double调用后')//顺序:4
}

console.log('getResult调用前')//顺序:1
getResult();
console.log('getResult调用后')//顺序:3

/*****依次输出如下*****/
getResult调用前
double调用前
getResult调用后
20//1s后输出
double调用后

①首先打印输出getResult调用前,同步代码,顺序执行;

①首先打印输出getResult调用前,同步代码,顺序执行;
②然后调用方法getResult( ),打印输出double调用前,同步代码,顺序执行;③再调用异步方法double( )如果此处没有使用await关键字修饰,则依次输出的是:getResult调用前、double调用前、double调用后、getResult调用后、1s后输出20因为异步操作不会影响其他代码的执行,所以会将其他代码按顺序执行完,最后再执行double函数因为这里使用了await关键字,所以getResult( )的代码执行到这里就会被阻塞,等到double函数resolve了,再往下执行④尽管getResult函数内部被await阻塞了,由于getResult函数本身也是个async函数,所以它不会影响getResult函数外面的代码执行。因为调用async函数不会造成阻塞,它内部的所有阻塞都被封装在一个Promise对象中异步执行。⑤所以在调用getResult函数后,会继续向下执行,即打印输出getResult调用后⑥当1s之后,异步函数double执行完成,将结果交给resolve。⑦通过await关键字接收到double函数resolve的值,赋值给result变量。打印输出20⑧因为使用了await阻塞将异步变为同步,所以在打印输出20后再打印输出double调用后(2)处理reject回调

//方法一:通过promise对象的catch进行捕获
functiona(){
returnnewPromise((resolve,reject)=>{
setTimeout(()=>{
reject("something")
},1000)
})
}

asyncfunctionb(){
letr=awaita().catch((err)=>{
console.log(err)
})
}

//方法二:通过try/catch语句处理
functiona(){
returnnewPromise((resolve,reject)=>{
setTimeout(()=>{
reject("something")
},1000)
})
}

asyncfunctionb(){
letr=null
try{
r=awaita()
}catch(err){
console.log(err)
}
}

(3)使用await优化Promise对象的回调地狱问题在Promise章节中我们通过了Promise对象的then( )方法链式调用解决了回调地狱问题,但看起来仍然不够美观,我们可以通过await优化一下,让它看起来更符合我们平时代码的编写习惯。

//原本的解决方案
//第二个请求依赖于第一个请求的返回值,第三个请求依赖于第二个请求的返回值
request1().then(function(data){
returnrequest2(data)
}).then(function(data){
returnrequest3(data)
})
//这里只发送了三次请求,代码看起来还不错,虽然它已经比普通的回调函数形式好了很多。
//那如果需要发送五次或十次请求呢?代码也许会没那么美观,接下来我们使用学习到的await去解决这个问题。

原本的要求是每个请求都依赖于上一个请求的返回值,那么是不是得等一个请求完,才能发送下一个请求?这时我们可以思考一下,await的作用是什么?是不是对一个Promise对象去进行阻塞,使其状态变为fulfilled后获取resolve的值。这不就正是我们所需要的。

//使用await的解决方案
varres1=awaitrequest1()//将request1的返回值赋值给res1
varres2=awaitrequest2(res1)//将res1作为参数传给request2,并将request2的返回值赋值给res2
varres3=awaitrequest3(res2)//同理

//这样子写的代码更加的美观,并且更符合我们平时编写代码的习惯

“async属不属于es6属性”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注百云主机网站,小编将为大家输出更多高质量的实用文章!

相关推荐: C++分支和循环语句怎么使用

本篇内容介绍了“C++分支和循环语句怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!生活中存在三种语言结构(1)顺序结构(2)选择结构分支语句:if sw…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 02/16 14:04
下一篇 02/16 15:38

相关推荐