国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

如何在Promise鏈中共享變量?

_ang / 675人閱讀

摘要:那么,如何在這些回調(diào)函數(shù)之間共享變量呢這篇博客將探討這個問題。

譯者按: 使用Promise寫過異步代碼的話,會發(fā)現(xiàn)在Promise鏈中共享變量是一個非常頭疼的問題,這也是Async/Await勝過Promise的一點,我們在Async/Await替代Promise的6個理由有提過,這篇博客將有更詳細(xì)的介紹。

原文: Passing data between Promise callbacks

譯者: Fundebug

為了保證可讀性,本文采用意譯而非直譯,并且對源代碼進(jìn)行了大量修改。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。

基于Promise編寫異步代碼時,通常會使用多個then組成鏈?zhǔn)秸{(diào)用,每一個then都會有一個回調(diào)函數(shù)。因此,在Promise鏈中,會有很多回調(diào)函數(shù),每個回調(diào)函數(shù)都有一個獨(dú)立的變量作用域。那么,如何在這些回調(diào)函數(shù)之間共享變量呢?這篇博客將探討這個問題。

問題

connection變量在A處定義,在BC處都需要使用。但是,由于A、B、C處于各自獨(dú)立的作用域,connection變量將不能在BC處直接使用。

db.open()
    .then(connection => // A
    { 
        return connection.select(
        {
            name: "Fundebug"
        });
    })
    .then(result =>
    {
        connection.query(); // B
    })
    .catch(error =>
    {
        // ...
    })
    .finally(() =>
    {
        connection.close(); // C
    });
方法1:使用高階作用域變量

在更高階的作用域定義connection變量,在D處賦值,這樣在BC處直接使用了。

let connection; // A
db.open()
    .then(conn =>
    {
        connection = conn; // D
        return connection.select(
        {
            name: "Fundebug"
        });
    })
    .then(result =>
    {
        connection.query(); // B
    })
    .catch(error =>
    {
        // ...
    })
    .finally(() =>
    {
        connection.close(); // C
    });

問題:如果需要共享的變量過多(這是很常見的情況),則需要在高階作用域中定義很多變量,這樣非常麻煩,代碼也比較冗余。

方法2:嵌套作用域

將需要使用connection變量的Promise鏈內(nèi)嵌到對應(yīng)then回調(diào)函數(shù)中,這樣在BC處直接使用了。

db.open()
    .then(connection => // A
        {
            return connection.select(
                {
                    name: "Fundebug"
                })
                .then(result =>
                {
                    connection.query(); // B
                })
                .catch(error =>
                {
                    // ...
                })
                .finally(() =>
                {
                    connection.close(); // C
                });
        });

問題:之所以使用Promise,就是為了避免回調(diào)地域,將多層嵌套的回調(diào)函數(shù)轉(zhuǎn)化為鏈?zhǔn)降膖hen調(diào)用;如果為了共享變量采用嵌套寫法,則要Promise有何用?

方法3:return多個值

intermediate變量在A處定義并賦值,而在B處需要使用;但是,由于AB處于不同的作用域,B出并不能直接使用intermediate變量:

return asyncFunc1()
    .then(result1 =>
    { 
        const intermediate = ··· ; // A
        return asyncFunc2();
    })
    .then(result2 =>
    { 
        console.log(intermediate); // B
    });

A處使用Promise.all返回多個值,就可以將intermediate變量的值傳遞到B處:

return asyncFunc1()
    .then(result1 =>
    {
        const intermediate = ···; 
        return Promise.all([asyncFunc2(), intermediate]); // A
    })
    .then(([result2, intermediate]) =>
    {
        console.log(intermediate); // B
    });

問題: 使用Promise.all用于傳遞共享變量,看似巧妙,但是有點大材小用,并不合理;不能將變量傳遞到.catch()finally()中;當(dāng)共享變量過多,或者需要跨過數(shù)個.then(),需要return的值會很多。

方法4: 使用Async/Await

Async/Await是寫異步代碼的新方式,可以替代Promise,它使得異步代碼看起來像同步代碼,可以將多個異步操作寫在同一個作用域中,這樣就不存在傳遞共享變量的問題了!!!

方法1中的示例可以改寫為:

try
{
    var connection = await db.open(); // A 
    const result = await connection.select(
    {
        name: "Fundebug"
    });
    connection.query(); // B
}
catch (error)
{
    // ...
}
finally
{
    connection.close(); // C
}

方法3中的示例可以改寫為:

try
{
    result1 = await asyncFunc1();
    const intermediate = ··· ;
    result2 = await asyncFunc2();
    console.log(intermediate);
}
catch (error)
{
    // ...
}

毋庸贅言,Async/Await直接將問題消滅了,無疑是更好的方式!

參考

Promises for asynchronous programming

ES proposal: Promise.prototype.finally()

ES proposal: Promise.try()

Async/Await替代Promise的6個理由

版權(quán)聲明:
轉(zhuǎn)載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/201...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88557.html

相關(guān)文章

  • 一個真實的Async/Await示例

    摘要:如果不希望定義多余的外層變量,則需要在鏈中的每一個函數(shù)中都返回變量,這樣做顯然更加糟糕。 譯者按: 通過真實的代碼示例感受Async/Await的力量。 原文: Async/await - A thorough example 譯者: Fundebug 為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。 既然Node.js 8已經(jīng)LTS了,我想大...

    habren 評論0 收藏0
  • 春招季如何橫掃 Javascript 面試核心考點(基礎(chǔ)版)?

    摘要:當(dāng)前函數(shù)執(zhí)行完成后,當(dāng)前函數(shù)的執(zhí)行上下文出棧,并等待垃圾回收。作用域與作用域鏈到來有全局作用域函數(shù)作用域和塊級作用域新增。 引言 Javascript是前端面試的重點,本文重點梳理下 Javascript 中的常考知識點,然后就一些容易出現(xiàn)的題目進(jìn)行解析。限于文章的篇幅,無法將知識點講解的面面俱到,本文只羅列了一些重難點,如果想要了解更多內(nèi)容歡迎點擊我的博客。 一、變量類型 1.JS ...

    impig33 評論0 收藏0
  • 春招季如何橫掃 Javascript 面試核心考點(基礎(chǔ)版)?

    摘要:當(dāng)前函數(shù)執(zhí)行完成后,當(dāng)前函數(shù)的執(zhí)行上下文出棧,并等待垃圾回收。作用域與作用域鏈到來有全局作用域函數(shù)作用域和塊級作用域新增。 引言 Javascript是前端面試的重點,本文重點梳理下 Javascript 中的常考知識點,然后就一些容易出現(xiàn)的題目進(jìn)行解析。限于文章的篇幅,無法將知識點講解的面面俱到,本文只羅列了一些重難點,如果想要了解更多內(nèi)容歡迎點擊我的博客。 一、變量類型 1.JS ...

    jayce 評論0 收藏0
  • JS異步編程之Promise

    摘要:三是控制反轉(zhuǎn)控制權(quán)在其他人的代碼上,假如異步函數(shù)是別人提供的庫,我們把回調(diào)函數(shù)傳進(jìn)去,我們并不能知道異步函數(shù)在調(diào)用回調(diào)函數(shù)之外做了什么事情。錯誤捕捉相比回調(diào)函數(shù)的錯誤無法在外部捕捉的問題,能夠為一連串的異步調(diào)用提供錯誤處理。 前言 《JS異步編程之 callback》一文我們了解了JS 是基于單線程事件循環(huán)的概念構(gòu)建的,回調(diào)函數(shù)不會立即執(zhí)行,由事件輪詢?nèi)z測事件是否執(zhí)行完畢,當(dāng)執(zhí)行完有...

    Hegel_Gu 評論0 收藏0
  • 【譯】JavaScript 核心(第二版)

    摘要:技術(shù)上來說這個機(jī)制被稱為動態(tài)分配或代理。定義類一個類是一個正式的抽象集,它規(guī)定了對象的初始狀態(tài)和行為。技術(shù)上來說一個類表示構(gòu)造函數(shù)原型的組合。因此構(gòu)造函數(shù)創(chuàng)建對象并自動設(shè)置新創(chuàng)建實例的原型。第二次調(diào)用時,相同的上下文再次被壓入棧并恢復(fù)。 原文:JavaScript. The Core: 2nd Edition作者:Dmitry Soshnikov 文章其他語言版本:俄語 這篇文章是 ...

    dingding199389 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<