We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
简单来说,它们是基于promises的语法糖,使异步代码更易于编写和阅读。通过使用它们,异步代码看起来更像是老式同步代码,因此它们非常值得学习。
async function hello() { return "Hello" }; hello(); //Promise {<fulfilled>: "Hello"}
上面的代码增加async关键字后,这个函数会返回promise。这是异步的基础,可以说,现在的异步JS就是使用promise。
箭头函数写法
let hello=async ()=>{return 'hello'}
现在我们可以使用.then方法啦
.then
hello().then((mes)=>{console.log(mes)})
await只在异步函数里面才起作用,它的主动作用是会暂停代码在该行上,直到promise完成,然后返回结果值,await后面应该放promise对象
await
promise
我们可以造一个实际的例子
const p=new Promise((resolve,reject)=>{ setTimeout(resolve,3000,'doing') }) const r=new Promise((resolve,reject)=>{ setTimeout(resolve,0,p) }) const o=r.then((mes)=>{ return mes+'=>done' }) o.then((mes)=>{console.log(mes)}).catch((error)=>{console.log(error)}) //doing => done
上面代码中,r会拿到p的结果,然后链式调用下去。
我们可以使用async+await进行封装
async
function promise(ms, mes) { return new Promise((resolve, reject) => { setTimeout(resolve, ms, mes); }); } async function fn() { const p = await promise(3000, "doing"); console.log(p); // doing const r = await promise(0, p); console.log(r); //doing const o = await (r + "=>done"); console.log(o); //doing =>done } fn();
可以看到上面的异步代码就跟同步代码的写法一样。
async和await要同时使用才会有异步的效果,单单使用async依然是同步代码,只是返回promise对象
在使用async/await关键字的时候,错误处理是关键,一般我们会这么写来捕捉错误
async/await
function ajax(){ return Promise.reject(1) } async function fn(){ try{ const result=await ajax() console.log(result) }catch(error){ console.log(error) } } fn()
下面我们可以使用更好的方法
function ajax(){ return Promise.reject(1) } function ErrorHandler(error){ throw Error(error) } async function fn(){ const result=await ajax().then(null,(error)=>{ErrorHandler(error)}) console.log('result',result) } fn()
这里要注意的就是ErrorHandler时不要用return,以免把结果返回给result,使用throw Error就可以抛出一个错误。那么后续的代码就不会执行了
ErrorHandler
return
result
throw Error
function async2(){ console.log('async2') } async function fn(){ console.log('fn') await async2() //同步的 console.log('我是异步?') } fn() console.log('end') //fn //async2 //end //我是异步?
最后的console.log('我是什么步?')是后于await关键字的,说明它是异步的,如果我们想执行同步代码,最好都放在await的上面,因为有时候await会带给我们疑惑,会误以为没有写await关键字的代码是同步的。
console.log('我是什么步?')
也许你会怀疑是否第一行log也是异步的,下面这个代码可以告诉你答案,并非写了async关键字就代表这是异步函数。
let a=0 async function fn(){ console.log(a) await Promise.resolve(333).then((r)=>{console.log(r)}) console.log('我是什么步?') } fn() console.log(++a) //结果 /* 0 1 333 "我是什么步?" */
await天生是串行的,所谓串行,就是按照顺序执行。
function async2(delay){ return new Promise((resolve)=>{ setTimeout(()=>{ console.log('执行') resolve() },delay) }) } async function fn(){ await async2(5000) await async2(2000) await async2(1000) } fn()
由于async跟setTimeout同时用没有效果,所以我使用上面的代码做实验,log台五秒钟后会分别打印,这说明默认就是按照顺序执行await的
log
如果想要并行,就可以使用Promise.all或者forEach方法
Promise.all
forEach
function fn(){ await Promise.all([async2(5000),async2(2000),async2(1000)]) }
function async2(delay){ return new Promise((resolve)=>{ setTimeout(()=>{ console.log('执行') resolve() },delay) }) } function fn3(ms){ return function fn(){ async2(ms) } } [fn3(5000),fn3(2000),fn3(1000)].forEach(async (v)=>{ await v() })
fetch就是使用promise版本的XMLHttpRequest
fetch
XMLHttpRequest
fetch('products.json').then(function(response) { return response.json(); }).then(function(json) { console.log(json) }).catch(function(err) { console.log('Fetch problem: ' + err.message); });
上面的代码的意思是通过fetch申请一个json数据,然后得到数据后将其json化,再打印出来。
转化成async和await方法
const promise=()=>{ try{ const j=await fetch('products.json') const result=await j.json() console.log(result) }catch(error){ console.log(error) } } promise()
我们有一个名为 f 的“普通”函数。你会怎样调用 async 函数 wait() 并在 f 中使用其结果?
async function wait() { await new Promise(resolve => setTimeout(resolve, 1000)); return 10; } function f() { // ……这里你应该怎么写? // 我们需要调用 async wait() 并等待以拿到结果 10 // 记住,我们不能使用 "await" }
其实解决方法很简单,由于 await 会返回一个 promise,所以直接在后面写 then 方法就可以拿到结果
function f() { wait().then(result => alert(result)); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
async和await
简单来说,它们是基于promises的语法糖,使异步代码更易于编写和阅读。通过使用它们,异步代码看起来更像是老式同步代码,因此它们非常值得学习。
async关键字
上面的代码增加async关键字后,这个函数会返回promise。这是异步的基础,可以说,现在的异步JS就是使用promise。
箭头函数写法
现在我们可以使用
.then
方法啦await关键字
await
只在异步函数里面才起作用,它的主动作用是会暂停代码在该行上,直到promise
完成,然后返回结果值,await
后面应该放promise
对象我们可以造一个实际的例子
上面代码中,r会拿到p的结果,然后链式调用下去。
我们可以使用
async
+await
进行封装可以看到上面的异步代码就跟同步代码的写法一样。
async
和await
要同时使用才会有异步的效果,单单使用async
依然是同步代码,只是返回promise
对象错误处理
在使用
async/await
关键字的时候,错误处理是关键,一般我们会这么写来捕捉错误下面我们可以使用更好的方法
这里要注意的就是
ErrorHandler
时不要用return
,以免把结果返回给result
,使用throw Error
就可以抛出一个错误。那么后续的代码就不会执行了await的传染性
最后的
console.log('我是什么步?')
是后于await
关键字的,说明它是异步的,如果我们想执行同步代码,最好都放在await
的上面,因为有时候await会带给我们疑惑,会误以为没有写await
关键字的代码是同步的。也许你会怀疑是否第一行log也是异步的,下面这个代码可以告诉你答案,并非写了
async
关键字就代表这是异步函数。串行和并行
await
天生是串行的,所谓串行,就是按照顺序执行。由于async跟setTimeout同时用没有效果,所以我使用上面的代码做实验,
log
台五秒钟后会分别打印,这说明默认就是按照顺序执行await的如果想要并行,就可以使用
Promise.all
或者forEach
方法与fetch相结合
fetch
就是使用promise
版本的XMLHttpRequest
上面的代码的意思是通过fetch申请一个json数据,然后得到数据后将其json化,再打印出来。
转化成async和await方法
在非 async 函数中调用 async 函数
我们有一个名为 f 的“普通”函数。你会怎样调用 async 函数 wait() 并在 f 中使用其结果?
其实解决方法很简单,由于 await 会返回一个 promise,所以直接在后面写 then 方法就可以拿到结果
The text was updated successfully, but these errors were encountered: