【发布时间】:2018-08-01 00:08:01
【问题描述】:
正如标题所示,我正在尝试使用 promise 来设置我的 react 组件的状态。很简单,对吧?也许不吧。好吧,当我尝试在承诺中进行后续的 ajax 调用时,问题就出现了。
代码如下。如您所见,我正在尝试映射我返回的数据并创建一个新对象。在创建该对象时,还有另一个应设置其中一个字段的 promise 调用。所有这些都可以正常工作,但是在第二个承诺完成之前设置状态并且该字段对我不可用。
我尝试使用 async/await 让它等待调用完成,但我在这种方法中也没有成功。
如果您有任何建议,我们将不胜感激。
我在 ComponentDidMount 方法中进行调用:
public componentDidMount(): void {
this._spApiService
.getListItems(this.props.context, "Company News")
.then((spNewsStories: SpNewsStory[]) => {
return spNewsStories.map((newsStory: SpNewsStory) => {
return new AdwNewsStory(newsStory, this.props.context);
});
})
.then((adwNewsStories: AdwNewsStory[]) => {
this.setState({
topStories: adwNewsStories,
});
});
}
这是进行第二次 ajax 调用的 AdwNewStory 类:
import { SpNewsStory } from "./SpNewsStory";
import { ISpApiService } from "../../interfaces/ISpApiService";
import SpApiService from "../../services/SpApiService";
import { WebPartContext } from "../../../node_modules/@microsoft/sp-webpart-
base";
import { SpAttachment } from "../SpAttachment";
import IEnvironmentService from "../../interfaces/IEnvironmentService";
import EnvironmentService from "../../services/EnvironmentService";
import { IAdwDateTimeService } from "../../interfaces/IAdwDateTimeService";
import AdwDateTimeService from "../../services/AdwDateTimeService";
class AdwNewsStory {
public id: number;
public title: string;
public publishDate: string;
public storySummary: string;
public storyLink: string;
public windowTarget: string;
public imageUrl: string;
public imageAlternativeText: string;
public attachments: boolean;
private _spApiService: ISpApiService;
private _context: WebPartContext;
private _environmentService: IEnvironmentService;
private _adwDateTimeService: IAdwDateTimeService;
constructor(spNewsStory: SpNewsStory, context?: WebPartContext) {
this._spApiService = new SpApiService();
this._context = context;
this._environmentService = new EnvironmentService();
this._adwDateTimeService = new AdwDateTimeService();
this.buildAdwNewsStory(spNewsStory);
}
private buildAdwNewsStory = (spNewsStory: SpNewsStory): void => {
this.id = spNewsStory.Id;
this.title = spNewsStory.Title;
this.publishDate = this.setPublishDate(spNewsStory.PublishDate);
this.storySummary = spNewsStory.StorySummary;
this.storyLink = spNewsStory.Link.Description;
this.windowTarget = spNewsStory.WindowTarget;
this.imageAlternativeText = spNewsStory.ImageAlternateText;
this.attachments = spNewsStory.Attachments;
if (this.attachments) {
this.setImageUrl();
}
};
private setImageUrl = (): void => {
this._spApiService.getListItemAttachments(this._context, "Company News", this.id).then(attachments => {
const siteUrl: string = this._environmentService.getSiteUrl();
const attchmentUrl: string = `${siteUrl}/Lists/Company%20News/Attachments/${this.id}/${attachments[0].FileName}`;
this.imageUrl = attchmentUrl;
});
};
private setPublishDate = (dateString: string) => {
const publishDate: Date = new Date(dateString);
return `${this._adwDateTimeService.getMonthName(publishDate.getMonth())} ${publishDate.getDate()}, ${publishDate.getFullYear()}`;
};
}
export default AdwNewsStory;
【问题讨论】:
-
我还没有完整的答案,但我会强烈敦促您重新考虑您的设计。虽然没有技术上的理由不这样做,但在构造函数中使用 Promises 可能不是一个好主意,因为无法从调用站点真正得知该 Promise 何时解决。
-
这会直接导致您遇到的问题。
-
"在创建该对象时,还有另一个应设置字段的承诺调用" - 你永远不会等待那个承诺,是的。另外,just don't use promises inside constructors。首先获取您的附件(并明确链接您的承诺),然后构建对象。
标签: javascript reactjs typescript