[英]Async function in a promise callback
我正在尝试做这样的事情,但它正在中断:
myAsyncFunction = async () => {
fetchResource().then( res => {
await fetchAnotherResource()
....
})
}
在完成第一个承诺的过程中,我想使用await表达式,但是它看起来不像该回调的范围允许异步函数。
通过上面的方法,它告诉我await是一个保留关键字(在这种情况下,由于我想的范围,它对await没有任何意义?)
如果我用如下async
声明匿名函数:
fetchResource().then( async (res) => {...})
我收到这样的语法错误:
ProductForm.jsx?130a:143 Uncaught (in promise) TypeError: (0 , _context.t1) is not a function
我不确定是否相关,但这在React组件内部。
有没有一种语法可以完成我在这里要做的事情? (使用异步函数作为Promise处理程序)
编辑:相关代码 (对不起,代码转储)
initializeState = async () => {
getShopInfo(this.state.shop_id)
.then (async (res) => {
if (product_id) {
({ activeLocalization, localizations } = await this.initializeEditState(product_id, defaultLocalization, localizations))
} else {
({ activeLocalization, localizations } = await this.initializeBlankState(defaultLocalization, localizations))
}
})
}
initializeEditState = (product_id, defaultLocalization, localizations, allCategoriesPromises) => {
return new Promise( resolve => {
let productPromiseArray = []; // storage for auxiliary localization requests
let filledOutLocalizations = []; // hold localizations that have been merged with the product data
getProduct(product_id, defaultLocalization.localization_id)
.then( json => {
/* fetch object that will represent a product in state
* and merge it with the default localization object */
let defaultProductState = this.setupEditProductState(json)
defaultLocalization = Object.assign(defaultLocalization, defaultProductState)
/* setup promise array for all other localizations */
localizations.forEach( l => {
productPromiseArray.push(getProduct(product_id, l.localization_id))
})
/* fetch other products and merge them with localizations */
Promise.all( productPromiseArray )
.then( resultArray => {
resultArray.forEach( res => {
/* test for fail condition here;
* fail condition happens when new localizations
* are registered between edits */
let loc = localizations.find(
l => l.localization_id == res.data.product.localization_id
)
if (res.result) {
loc = Object.assign(loc, this.setupEditProductState(res))
} else {
/* Default state for this localization
* (you should have access to defaultLocalization) */
loc = Object.assign(defaultProductState, loc)
}
filledOutLocalizations.push(loc)
})
/* Finally, get ALL category lists and
* INITIALIZE EDIT STATE */
let promiseArray = []
for (var filLoc of filledOutLocalizations) {
promiseArray.push(getAllCategories(filLoc.localization_id))
}
resolve({ activeLocalization: defaultLocalization, localizations: filledOutLocalizations })
})
})
})
}
initializeBlankState = ( defaultLocalization, localizations ) => {
return new Promise( resolve => {
let activeLocalization = Object.assign(
defaultLocalization,
this.getBlankState(defaultLocalization.localization_id)
)
activeLocalization.product.enable_flg = 1
localizations = localizations.map( l => {
return Object.assign(l, this.getBlankState(l.localization_id))
})
resolve({ activeLocalization, localizations })
})
}
该代码在您的原始版本中不起作用,因为await
只能在async
函数中使用。 在函数内部then
有它自己的范围,该范围不涉及外一个再; 因此使用await
无效。
第二个版本,其中你把async
里面then
是违反返回类型。 根据Promise.prototype.then
MDN定义 :
then()方法返回一个Promise
和MDN定义 async function
:
异步函数声明定义了一个异步函数,该函数返回一个AsyncFunction对象
您会看到这两个不应同时使用。
通常, async-await
用来代替Promise - then - catch
,而不是一起使用。 因此,对于您的示例函数,应为:
myAsyncFunction = async () => {
const resource = await fetchResource();
if (isValidResource(resource)) {
const anotherResource = await fetchAnotherResource();
...
}
}
对于您的函数initializeState
,它使用async
:
initializeState = async () => {
const res = await getShopInfo(this.state.shop_id);
if (product_id) {
({ activeLocalization, localizations } = await this.initializeEditState(product_id, defaultLocalization, localizations))
} else {
({ activeLocalization, localizations } = await this.initializeBlankState(defaultLocalization, localizations))
}
}
从我的角度来看, async
then(..)
在您的情况下是多余的。 只需继续使用Promises。在fetchResource().then( res => fetchAnotherResource()).then(res=>{code...})
最后一个代码将等待fetchAnotherResource(..)
完成。 所以,你的代码
.then (async (res) => {
if (product_id) {
({ activeLocalization, localizations } = await this.initializeEditState(product_id, defaultLocalization, localizations))
} else {
({ activeLocalization, localizations } = await this.initializeBlankState(defaultLocalization, localizations))
}
})
可以像这样重写
.then ((res) => product_id?
this.initializeEditState(product_id, defaultLocalization, localizations)):
this.initializeBlankState(defaultLocalization, localizations))
)
.then(({activeLocalization,localizations})=>{.....})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.