2017-07-27 44 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)))