2017-07-27 60 views
3

內等待似乎有什麼內在的錯誤必須定義一個無極的回調異步:使用無極

return new Promise(async (resolve, reject) => { 
    const value = await somethingAsynchronous(); 
    if (value === something) { 
    return resolve('It worked!'); 
    } else { 
    return reject('Nope. Try again.'); 
    } 
}); 

這顯然是一個antipattern和有編碼problems which can arise from it。據我所知,它變得更容易在這裏未能發現錯誤,把裏面try/catchawait報表時也是如此。

我的第一個問題是,什麼是編寫這樣的事情最好的辦法,當一個人想轉發的承諾與決心不同/拒絕值?隨着/ catch?即

return new Promise((resolve, reject) => { 
    somethingAsynchronous().then(value => { 
    if (value === something) { 
     return resolve('It worked!'); 
    } else { 
     return reject('Nope. Try again.'); 
    } 
    }); // errors would now be propagated up 
}); 

或者你只是把它拿出來的無極構造完全的建議here

async function outerFunction() { 
    const value = await somethingAsynchronous(); 
    return new Promise((resolve, reject) => { 
    if (value === something) { 
     return resolve('It worked!'); 
    } else { 
     return reject('Nope. Try again.'); 
    } 
    }); 
} 

但是如果在outerFunction()中有多個await語句,即調用多個異步函數的線性代碼塊,會發生什麼情況。那麼你每次都必須創建並返回一個新的Promise嗎?

但是那你怎麼解釋這樣的代碼呢?

async function outerFunction() { 
    if (someSynchronousCheck()) { 
    return 'Nope. Try again.' // another reject case 
    } 

    const value = await somethingAsynchronous(); 
    // ... 
} 

我有這樣的感覺,我會讓它比它應該更復雜。我試圖避免嵌套回調/鏈接然後/ catch塊沒有在未來創建更多的問題。

我的最後一個問題是,爲什麼回調傳遞給無極不是天生async?它已經被封裝在一個promise中,並期望異步調用解析/拒絕函數。

+0

始終牢記,基本上_only_時間'新Promise'需要的是,如果你是一個不同的API互操作使用回調。 – loganfsmyth

回答

9

你這樣做:

async function outerFunction() { 
    const value = await somethingAsynchronous(); 
    if (value === something) { 
    return 'It Worked!'; 
    } 
    throw Error('Nope. Try again.'); 
} 

使用async包裝的outerFunction與承諾的結果。

如果你想要那個包裹承諾解決的東西,剛剛從async函數返回。如果您希望包裝承諾被拒絕,請在async函數內發出錯誤。

但是那你怎麼解釋這樣的代碼呢?

async function outerFunction() { 
    if (someSynchronousCheck()) { 
    throw Error('Nope. Try again.'); 
    } 

    const value = await somethingAsynchronous(); 
    // ... 
} 
+0

最後一段恰恰是我需要的答案。我試圖弄清楚如何在異步函數中「拒絕」某些東西。 – Druckles

+0

「使用異步包裝帶有Promise的outerFunction的結果。」 - 謝謝! – FloatingRock

0

new Promise(async (resolve, reject) => { ... })是相對較新的反模式。它導致創建2個promise對象而不是1個,在構造函數中發生的未捕獲錯誤不能被try..catch捕獲並導致未處理的拒絕。

考慮承諾異步代碼可以與async..await處理,當前使用情況爲Promise構造是非諾異步代碼,例如:

new Promise(resolve => setTimeout(resolve, 1000)) 

Promise構造包含同步碼或涉及其他承諾,一個承諾應該用async函數構造。一個簡易的更換async IIFE:

return (async (resolve, reject) => { 
    const value = await somethingAsynchronous(); 
    if (value === something) { 
    return 'It worked!'; 
    } else { 
    throw 'Nope. Try again.'; 
    } 
})(); 

如果需要Promise構造函數時所用async一起使用仍然存在,Promise構造應在層次結構中向下移動,這樣就不會換任何async功能。

我的最後一個問題是,爲什麼回調傳遞給承諾不是固有的異步?它已經被封裝在一個promise中,並期望異步調用解析/拒絕函數。

async功能不僅是異步執行的功能時,它返回一個應該被利用另一個承諾 - 或catch至少處理。 Promise不應該利用從構造函數返回的承諾。

構造函數可以在相同的刻度上解析,並且不一定非要異步。

Promise.resolve(1); 

類似於

Promise(resolve => resolve(1)) 

,而不是

Promise(resolve => setTimeout(() => resolve(1)))