2016-11-22 35 views
5

我還沒有看到這些結構用得不多,但我發現自己寫他們使用異步電動機/等待在函數通常不會返回一個承諾,例如ES8立即調用異步函數表達式

chan.consume(queue, (msg) => { 
    this.pendingMsgs++; // executed immediately 
    (async() => { 
    await this.handleMessage(msg); 
    this.pendingMsgs--; 
    if (cancelled && this.pendingMsgs === 0) { 
     await chan.close(); 
     await this.amqpConnectionPool.release(conn); 
    } 
    })(); 
}); 

,而不是

chan.consume(queue, async (msg) => { // external lib does not expect a return value from this callback 
    this.pendingMsgs++; // executed in promise context(?) 
    await this.handleMessage(msg); 
    this.pendingMsgs--; 
    if (cancelled && this.pendingMsgs === 0) { 
     await chan.close(); 
     await this.amqpConnectionPool.release(conn); 
    } 
}); 

chan.consume(queue, (msg) => { 
    this.pendingMsgs++; // no await - excess function decls & nesting 
    this.handleMessage(msg).then(() => { 
    this.pendingMsgs--; 
    if (cancelled && this.pendingMsgs === 0) { 
     chan.close().then(() => { 
     this.amqpConnectionPool.release(conn); 
     }); 
    } 
    }); 
}); 

這是 '事'?我應該知道這裏有缺陷嗎? 在這種情況下使用異步/等待的內容是什麼?

+0

什麼是這樣做的意義何在? – Pointy

+0

@Pointy - 有沒有一些明顯的選擇我忽略了? –

+2

@DrewR將返回值添加到當前不返回任何內容的函數不會違反任何替換原則。那麼爲什麼還要把所有東西都包裝在另一個函數和縮進層中呢? –

回答

4

這是 '事'?

是的。它偶爾會出現,例如here。他們被稱爲IIAFEs :-)
如果你想要把重點放在箭頭,你也可以打電話給他們IIAAFs。

都在這裏有陷阱,我應該知道的?

每當你調用promise函數並且不把結果返回到別的地方時,你自己負責承諾 - 這意味着你必須處理它的錯誤。所以模式應該總體上看起來像

(async() => { 
    … 
})().catch(err => { 
    console.error(err); 
}); 

如果你不想關心未處理拒絕事件。

在這種情況下使用async/await的內容是什麼?

並不多,與then版本相比。但是,你說,這可能會在圖書館的不兼容的異步回調暗示「外部LIB不會從該回調期待一個返回值」,所以要小心你在做什麼的時候。它也可能取決於例外是從回調同步引發,所以一切都取決於庫的預期,這裏什麼(如果沒有期待,是否可能在將來改變)。如果庫將開始專門處理承諾返回值,則不希望將來出現不兼容。

不過,我還是會建議直接直接傳遞async功能,因爲其更好的可讀性回調的第二圖案。如果你想避免返回一個承諾到庫中,創建一個包裝回調一個輔助函數:

function toVoid(fn) { 
    return (...args) => void fn(...args); 
} 
function promiseToVoid(fn) { 
    return (...args) => void fn(...args).catch(console.error); 
} 

,你可以使用這樣的:

chan.consume(queue, toVoid(async (msg) => { 
    … // use `await` freely 
})); 
+0

我喜歡包裝功能的想法。 謝謝。 –

+0

對未處理諾言拒絕的說明給予了很多讚譽 - 這是一個很好的答案。異步口袋函數現在開始在很多文檔中彈出,並且很多人忽略了將非插入函數插入非異步函數時可能發生的錯誤。我還要說,值得指出的是'.catch()'只有在你不使用'await'調用pocket函數時纔是必須的。即運行'await(async()=> {})();'沒有添加'.catch()'就沒有問題。但是,如果你離開'await',那麼你必須記住最後鏈接'.catch()'。 – mikermcneil

相關問題