【发布时间】:2021-06-07 16:24:21
【问题描述】:
我在我的代码中经常看到这个问题,并且我在这里看到过类似的帖子,但它们似乎与我的问题没有特别的联系,这让我觉得我在某个地方遗漏了一些东西。
注释'await' has no effect on the type of this expression.ts(80007) 出现在下面的异步方法中(作为示例)...
/**
* Deletes the account for the currently logged in user.
*/
async deleteAccount() {
Logger.log('Deleting the currently logged in user', 'Auth')
const service = ServiceFactory.profile()
const operationState = await service.deleteUser()
if (!operationState.succeeded)
operationState.throw()
},
通过堆栈,通过如下方式调用ProfileService类中的该方法,该类在ServiceFactory.profile()中返回...
/**
* Deletes a user.
* @returns {ServiceOperation} The operation result.
* @memberof ProfileService
*/
async deleteUser() {
const operationState = new ServiceOperation('Delete User', true)
const url = `${ this.baseUrl }?SchemeId=${ this.schemeId }`
Logger.log(url, 'Request [DELETE]')
try {
return this.processResponse(await Axios.delete(url), operationState, 'deleteUser')
} catch (err) {
return this.failOperation(err, operationState, 'deleteUser')
}
}
该问题似乎与基类上的 processResponse 方法有关,该方法将我的 JSON 响应从后端转换为 ServiceOperation 类,该类跟踪运行状态、成功、合并多个结果并将不同类型的错误响应转换为与应用程序处理一致 - 此处添加的代码在很大程度上无关紧要......
/**
* Handles a succesfull data changing operation and processes the response safely.
*
* @param {Object} response The service response.
* @param {ServiceOperation} operationState
* @param {string} [methodName='?'] The name of the calling method.
* @returns {ServiceOperation} The modified operation state.
*
* @memberof Service
*/
processResponse(response, operationState, methodName = '?') {
if (response.data !== false && !response.data || response.data == null) {
operationState.complete(true)
} else {
operationState.complete(true, response.data)
}
Logger.logObject(response, `Operation completed [${ methodName }]`, this.loggingCategory)
return operationState
}
failOperation 只是processResponse 失败调用方法...
/**
* Handles a failed operation.
*
* @param {Error} error
* @param {ServiceOperation} operationState
* @param {string} [methodName='?'] The name of the calling method.
* @returns {ServiceOperation} The modified operation state.
*
* @memberof Service
*/
failOperation(error, operationState, methodName = '?') {
operationState.fail(error)
Logger.logObject(operationState, `Data service failed [${ methodName }]`, this.loggingCategory)
return operationState
}
上述两个方法都是Service 类的一部分,该类被扩展为之前包含deleteUser 函数的ProfileService 类(Service 类充当每个应用中的服务类。
我在这里有点困惑的是processResponse 不是async(也不需要是)。等待的调用在调用它的方法中被等待。这只是编辑器没有捡起它的一个案例,还是我怀疑,当我处理数据时我失去了潜在的承诺 - 如果是这样的话,我如何才能让该方法浮出水面的承诺processResponse 需要的结果?
processResponse 是一种通用方法,可以处理我在我的应用程序中拥有的所有服务方法结果,因此合并这些方法是不可行的。我考虑过让processResponse 本身为async 并在其上使用await,但从逻辑上讲,这似乎完全不会做任何事情,因为没有什么可以真正等待。
从功能上看,应用程序代码似乎工作正常,所以我不愿意在这个级别开始将它拆开,直到我完全理解它为什么会抱怨。
额外(但可能无关)信息
这是Service 类及其派生类使用的ServiceOperation 类的定义。这仅用于完成,并且在很大程度上无关紧要。
/**
* Defines an operation performed through a service.
*
* @export
* @class ServiceOperation
*/
export default class ServiceOperation {
/**
*Creates an instance of ServiceOperation.
* @param {string} name
* @param {boolean} [started=false]
* @memberof ServiceOperation
*/
constructor(name, started = false) {
this.name = name
this.running = started
this.completed = false
this.succeeded = false
}
/**
* Completes a service operation.
*
* @param {boolean} succeeded
* @param {object} data Any data or error info returned
* @returns {ServiceOperation} itself.
* @memberof ServiceOperation
*/
complete(succeeded, data) {
this.running = false
this.completed = true
this.succeeded = succeeded
if (data !== undefined && data !== null || this.data !== undefined && this.data !== null)
this.data = data
return this
}
/**
* Fails a service operation.
*
* @param {string} error An error
* @returns {ServiceOperation} itself.
* @memberof ServiceOperation
*/
fail(error) {
this.complete(false)
if (error && error.response && error.response.data) {
this.data = error.response.data
this.errorObject = error
this.error = error.response.data.message ? error.response.data.message : error.message
this.errorObject.message = this.error
} else {
this.error = error && error.message ? error.message : error
this.errorObject = error
}
return this
}
/**
* Throws the wrapped error object back for interrogation.
*
* @memberof ServiceOperation
*/
throw() {
if (this.errorObject)
throw this.errorObject
else if (this.error)
throw new Error(this.error)
else
throw new Error('Service Operation error')
}
/**
* Merges another operation into this one, updating it's info.
*
* @param {ServiceOperation} operation
* @param {boolean} includeData If not set then the data item will be eradicated if it is present.
* @memberof ServiceOperation
*/
updateMergeFrom(operation, includeData = false) {
this.running = operation.running
this.completed = operation.completed
this.succeeded = operation.succeeded
if (!includeData && this.data)
delete this.data
else if (includeData && operation.data)
this.data = operation.data
if (operation.stillPending !== undefined)
this.stillPending = operation.stillPending
if (!this.error && operation.error)
this.error = operation.error
}
/**
* Generates an immediately completed operation.
*
* @static
* @type {ServiceOperation}
* @memberof ServiceOperation
*/
static get immediate() {
return new ServiceOperation('Immediate').complete(true)
}
}
【问题讨论】:
-
service.forgotPassword是否返回承诺?如果没有,那么await-ing 它大多是多余的。我不确定你的三段代码是如何联系起来的。 -
另外,我觉得有点奇怪,显然
forgottenPassword调用最终调用deleteUser。从一般角度来看似乎不正确。 -
async/await 只是 Promises 语法糖的关键字。
service.forgotPassword是否返回承诺? -
啊 - 我似乎患有复制/粘贴失明 - 哦,亲爱的......
-
已更新以将
forgottenPassword替换为deleteUser- 我有很多方法存在相同的问题,因此我认为processResponse在某种程度上是问题。
标签: javascript ecmascript-6 async-await