Javascript 带承诺的流类型(获取和#x27;s)
我创建了一个Fetch函数来使用JSON API,并为JSON对象定义了类型。我对如何定义Javascript 带承诺的流类型(获取和#x27;s),javascript,flowtype,Javascript,Flowtype,我创建了一个Fetch函数来使用JSON API,并为JSON对象定义了类型。我对如何定义getCurrentJobAPI函数的返回类型感到困惑,因为之后我做了大量.then()。返回值是最后一个。然后()?在我的代码中,last.then()是一个setState,那么它的类型是什么呢 getCurrentJobAPI = (): {} => { const url: string = `dummy_url&job_id=${this.props.cur
getCurrentJobAPI
函数的返回类型感到困惑,因为之后我做了大量.then()
。返回值是最后一个。然后()?在我的代码中,last.then()是一个setState,那么它的类型是什么呢
getCurrentJobAPI = (): {} => {
const url: string = `dummy_url&job_id=${this.props.currentJob}`;
return fetch(url, {credentials: 'include'})
.then((response) => {
return response.json();
})
.then((json: CurrentJob) => {
console.log(json);
const location = json.inventoryJob.location;
const ref_note = json.inventoryJob.note;
const id = json.inventoryJob.id;
const models = json.inventoryJobDetails.map((j) => {
return Object.assign({}, {
code: j.code,
qty: j.qty
})
});
this.setState({ currentCodes: models, location: location, ref_note: ref_note, id: id})
return json
})
.then((json: CurrentJob) => {
const barcodes = json.inventoryJob.history;
if (barcodes.length > 0) {
this.setState({apiBarcodes: barcodes})
}
this.calculateRows();
this.insertApiBarcodes();
this.setState({ initialLoad: true });
})
};
更新:
虽然我知道我应该将Promise
定义为getCurrentJobAPI
的返回值(请参阅的答案和注释),但我仍然不确定如果提取解析为JSON响应,为什么我不能编写Promise
[我已将我的.then()语句压缩到per的推荐中。]
以下是CurrentJob
的类型定义:
type Job = {
user_id: number,
status: 'open' | 'closed',
location: 'string',
history: {[number]: string}[],
note: string,
} & CommonCurrentJob;
type JobDetails = {
iaj_id: number,
code: number,
} & CommonCurrentJob;
type CommonCurrentJob = {
id: number,
qty: number,
qty_changed: number,
created_at: string,
updated_at: string
}
当链接then's时,结果总是一个承诺。 调用
then
时,返回值是另一个承诺,否则链接then是不可能的。
通过在整个链中使用console.log(),您可以很容易地看到这一点。因此,首先,作为免责声明,我是TypeScript用户,但我发现这个问题实际上适用于两种语言,并且有相同的答案 我创建了一个Fetch函数来使用JSON API,并为JSON对象定义了类型。我对如何定义getCurrentJobAPI函数的返回类型感到困惑,因为之后我做了大量的.then()操作。返回值是最后一个。然后()?在我的代码中,last.then()是一个setState,那么它的类型是什么呢
getCurrentJobAPI = (): {} => {
const url: string = `dummy_url&job_id=${this.props.currentJob}`;
return fetch(url, {credentials: 'include'})
.then((response) => {
return response.json();
})
.then((json: CurrentJob) => {
console.log(json);
const location = json.inventoryJob.location;
const ref_note = json.inventoryJob.note;
const id = json.inventoryJob.id;
const models = json.inventoryJobDetails.map((j) => {
return Object.assign({}, {
code: j.code,
qty: j.qty
})
});
this.setState({ currentCodes: models, location: location, ref_note: ref_note, id: id})
return json
})
.then((json: CurrentJob) => {
const barcodes = json.inventoryJob.history;
if (barcodes.length > 0) {
this.setState({apiBarcodes: barcodes})
}
this.calculateRows();
this.insertApiBarcodes();
this.setState({ initialLoad: true });
})
};
TL;DR:承诺
(见注释)。正如您所怀疑的,这实际上是承诺链中最后一个顶级的返回类型
现在让我们再深入一点
这里是您的示例,稍微修改一下,以利用类型推断,而不是注释由接收者声明为any
的回调参数
另外,这些回调参数注释相当于不安全的隐式强制转换,或者我们在TypeScript中称之为类型断言,它们与代码的形状有关。它们看起来像这样
所以我尽量减少这些,因为它们形成了一个微妙的陷阱
显然,这是一个void
函数。它没有return
语句。但是,作为一个异步
函数,它固有地返回一个承诺
,就像它作为显式承诺
链编写时一样
注意:void
是一种在Flow和TypeScript中被发现很有用的结构,用于表示函数的语义意图,这些函数不返回值,但实际上这些函数返回未定义的,因为这是JavaScript。Flow似乎无法将未定义的
识别为一个类型,但在TypeScript下,函数同样可以被注释为返回承诺
。毫无疑问,承诺
更可取,因为它提供了清晰的意图
备注:我使用和Windows的流二进制文件的组合完成了这项工作。Windows上的体验真的很糟糕,希望它能有所改善。回报价值就是整个承诺链。从技术上讲,您可以获取getCurrentJobAPI()
的结果,然后将更多的附加到和catch
中,并在其中键入内容。这就是你要问的吗?否则我不知道该说什么。您不能返回承诺本身以外的任何内容,否则它将不再是异步的。如果返回值是整个承诺链,我如何定义流中承诺的类型?这类案件的文件在哪里?你不能。异步不是这样工作的。如果您尝试在承诺链之后运行代码,它可能会在承诺结束之前运行。所以你不能认为它返回了一个值,因为这是同步的。对不起,我刚刚意识到我没有理解你的问题。我的回答不是对你的问题的回答,但这些问题几乎都不需要。使用。然后
返回另一个承诺,或者作为承诺链中的最终处理程序。大多数中间。然后
处理程序只返回未定义的
,这样您就可以将它们折叠成第一个。然后
。那么我该如何准确定义函数的返回类型呢?我是否定义了一个包含整个链的类型?在这种情况下,返回类型将是Promise。@AvremelKaminetzky是的,在Flow Promise中是一个类型生成类型(即,它将s a类型作为参数,并在内部生成一个类型基),因此您必须为Promise指定一个类型,例如,Promise
用于解析为字符串的承诺。您还可以使用Promise
让Flow了解它,并使用Promise
防止Flow检查承诺的实际类型(不建议使用,any
仅当您没有其他选择时才应使用)。@AvremelKaminetzky无论承诺如何解决!当然,这需要你真正理解你的承诺链——即负类型,仅仅是事物本身?如果你没有完全“得到”承诺,就很难谈论类型。您必须首先理解您的代码getCurrentJobAPI
解析承诺链的最后一个元素返回的内容。这个东西的类型就是承诺的类型——因为它总是返回一个承诺,所以您只需找出该承诺的解析形式。@AvremelKaminetzky JSON是一种字符串格式。您要么有一个JSON字符串(!!!)-要么有一个对象。不存在“JSON对象”这样的东西,事实上这个术语本身就是一个矛盾,就像“冰火”。可以将对象编码为JSON字符串。但是你有一根绳子。其中包含一个对象,但仅当您解码它时。
// @flow
import React from 'react';
type CurrentJob = {
inventoryJob: Job,
inventoryJobDetails: JobDetails[]
}
export default class A extends React.Component<{currentJob:JobDetails}, any> {
getCurrentJobAPI: () => Promise<void> = () => {
const url = `dummy_url&job_id=${String(this.props.currentJob)}`;
return fetch(url, {credentials: 'include'})
.then(response => {
return (response : {json(): any}).json();
}) // --> Promise<any>
.then(json => {
const currentJob = (json: CurrentJob); // make the assumption explicit.
console.log(currentJob);
const {location, id, note: ref_note} = currentJob.inventoryJob;
const currentCodes = currentJob.inventoryJobDetails
.map(({code, qty}) => ({
code,
qty
}));
this.setState({currentCodes, location, ref_note, id});
return currentJob;
}) // --> Promise<CurrentJob>
.then(currentJob => {
const apiBarcodes = currentJob.inventoryJob.history;
if (apiBarcodes.length > 0) {
this.setState({apiBarcodes});
}
this.setState({initialLoad: true});
}); // --> Promise<void>
};
}
// @flow
import React from 'react';
type CurrentJob = {
inventoryJob: Job,
inventoryJobDetails: JobDetails[]
}
export default class A extends React.Component<{currentJob:JobDetails}, any> {
getCurrentJobAPI = async () => {
const url = `dummy_url&job_id=${String(this.props.currentJob)}`;
const response = await fetch(url, {credentials: 'include'});
const json = await response.json();
const currentJob = (json: CurrentJob); // make the assumption explicit.
console.log(currentJob);
const {location, id, note: ref_note} = currentJob.inventoryJob;
const currentCodes = currentJob.inventoryJobDetails.map(({code, qty}) => ({
code,
qty
}));
this.setState({currentCodes, location, ref_note, id});
const apiBarcodes = currentJob.inventoryJob.history;
if (apiBarcodes.length > 0) {
this.setState({apiBarcodes});
}
this.setState({initialLoad: true});
};
}