es6 async和await


  es7 async和await ,作為genertor函數語法糖,在使用上比generator函數方便的,Generator 函數就是一個封裝的異步任務,或者說是異步任務的容器。異步操作需要暫停的地方,都用yield語句注明.

  generator將異步的流程標記的很簡潔,但是流程執行卻並不方便,所有我們需要借助Generator的自執行下函數。Thunk 函數可以用於generator函數的自流程管理

   async和await 作為generator的語法糖,自帶自執行器,相對於generator具有更好的語義,yield后面只能時promise,async,await 具有更好的適用性,並不明確規定是promise,async的返回的是promise

  1.asycn和await的基本使用

    async如果遇到await就會等待,等待其執行結果,才會往下繼續執行函數內部語句

/* 異步執行方法 */
function timeout(ms) {
    return new Promise((res)=>{
        console.log('settimeout')
        setTimeout(res,ms)
    })
}
/* await 只能在async定義的函數內部使用 */
async function asyncpriint(value,ms) {
    timeout(ms);
    console.log(value);
}
asyncpriint('hello world',2000);
// 先輸出settimeout等待2m鍾輸出hello world
// 如果去掉await,輸出settimeout並且不等待直接輸出hello world

  async函數返回的是一個promise

/* async返回時最終會轉成一個promise */
async function donow() {
    return 'czklove'
}
async function donow2 () {
    return new Promise(res=>{
        res('czklove')
    })
}
async function donow3 () {
    return Promise.resolve('czklove')
}
donow().then((val)=>{
    console.log(val)
})
// 輸出czklove
donow2().then((val)=>{
    console.log(val)
})
// 輸出czklove
/* 2和3是等價的,Promise.resolve 返回一個promise */
donow3().then((val)=>{
    console.log(val)
})
//輸出czklove
// 輸出輸出czklove
/* donow和donow2是等價的
    也就是說返回值是一個值的話,他會自動轉化成promise
 */
View Code

  async返回的promise對象的狀態變化

/* resolve */
async function promiseresolve(){
    await Promise.resolve('czkloveresolve')
    return 'czklove1'
}
/* rejuect */
async function promisereject(){
    await Promise.reject('czkloverejuct')
    console.log(123)
    return 'czklove2'
}
/* 內部都是resolve 
   一直執行下去
*/
promiseresolve().then(res=>{
    console.log('resolve'+res)
},rej=>{
    console.log('reject'+rej)
})
// resolveczklove1

/* 
    內部其中一個await是reject,則直接返回,不會再執行下去,並且返回值是rejuect的值
 */
promisereject().then(res=>{
    console.log('resolve'+res)
},rej=>{
    console.log('reject'+rej)
})
// 不會執行console.log(123)
// rejectczkloverejuct

  await  命令后面是一個promise對象,返回該對象的結果,如果不是promise,值直接放回該值

    如果后面是一個帶有then 方法的對象,那么會將其等同於promise

    await 后面的promise如果執行了rejuect 則整個函數終止,並且返回該對象的結果,返回的promise對象的狀態也是rejuect的

    如果我們想繼續執行下去,則可以將reject的promise 放入try catch 模塊中,另外一種是后面跟.catch 方法

/* 定義一個async 函數 */
async function awaitfc() {
    try {
        /* 放入try 和 catch 中 reject 不會終止函數執行 */
        await Promise.reject('czklove')
    } catch (e){

    }
    /* .catch 也可以使 reject 不會終止函數執行*/
    await Promise.reject('czklove').catch((e)=>{
        console.log(e)
    })
    return 'jgczklove'
}
awaitfc().then(val=>{
    console.log(val)
})
//czklove async.js
View Code

  函數的並發執行或繼發執行

/* 定義一個async 函數 */
let i = 1;
function settime(ms) {
    return new Promise((res)=>{
        setTimeout(()=>{
            res ('123'+(i++))
        },ms)   
    })
}
/* 繼發執行 */
async function funa() {
    let val1 = await settime(2000)
    console.log(val1)
    let val2 = await settime(2000)
    console.log(val2)
    let val3 = await settime(2000)
    console.log(val3)
    console.log('1111')
}
/* 並發執行 */
async function funa2() {
    let val1 = settime(2000);
    let val2 = settime(3000);
    let val3 = settime(2000);
    console.log(await val1)
    console.log(await val2)
    console.log(await val3)
    console.log(2222)
}
funa();
/* 
繼發執行
結果是順序的
    每隔2秒 輸出1231 1232 1233 ,最終輸出1111
*/
funa2();
/* 
並發
val1 val2 val3 輸出結果順序是不定的,但是可以確認,最終才輸出2222
 */

  使用promise.all 也可以達到並發執行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM