React提出的有问题的codelayer1提出的解决方案-控制多个Ajax调用存在直接在动作创建者内部访问状态的问题-反模式。
因此,如果不访问动作创建者内部的状态,我将监听组件中的batchRequestCompleted状态。当组件prop
batchRequestCompleted变为true(表示先前的请求已完成)时,我将检查是否有任何待处理的请求。如果是,我将调度操作以处理这些下一个请求。因此从根本上讲,佐贺将行动称为行动,而行动又会改变状态。修改状态后,将从组件分派另一个处理进一步请求的操作。这样,传奇就永远不会访问状态。
上面的解决方案听起来不错,但是要付出行动创建者完成之前路线更改中提到的问题。也就是说,如果在清除队列之前有人导航到其他路由,放置在队列中的请求将发生什么情况。
我可以解决React-控制多个Ajax调用中提到的问题,而无需访问动作创建者内部的状态,也不必使组件回到图片中以调度动作来清除挂起的队列。
我做了一些回购github.com/adz5a/so-stream-example
来说明我将如何解决您的问题。
此仓库使用两个库xstream
和recompose
。前者通过其运算符提供ObservableStreams的实现,而后者则通过React进行连接。
在一切之前必须有一个概念:ES
Observables
。它们覆盖在文章的深度,如这个(我强烈建议阅读和听力从莱什奔过去的文章/会谈,对这个问题)。
Observabes是一种惰性原语,用于随时间建模值。在JS中,我们还有另一个用于执行异步操作的原语:Promises。这些模型eventualvalue or error
并不因此而懒惰,而是渴望。对于React组件(或更常见的是UI),我们对延迟很感兴趣,因为 事情可能出错
:用户可能想要中断长时间运行的进程,它可能崩溃,更改路线等。
那么,我们如何解决您的问题:控制一个长时间运行的进程,该进程可能会由于用户交互而中断(获取很多行)?
首先,UI:
export class AnswerView extends React.Component {
static propTypes = {
// called when the user make a batch
// of request
onStart: PropTypes.func.isRequired,
// called when you want to stop the processing
// of requests ( when unmounting or at the request
// of the user )
onStop: PropTypes.func.isRequired,
// number of requests completed, 0 by default
completedRequests: PropTypes.number.isRequired,
// whether it's working right now or not
processing: PropTypes.bool.isRequired
};
render () {
// displays a form if no work is being done,
// else the number of completed requests
return (
<section>
<Link to="/other">Change Route !</Link>
<header>
Lazy Component Example
</header>
{
this.props.processing ?
<span>{"requests done " + this.props.completedRequests}<button onClick={this.props.onStop}>Stop !</button></span>:
<form onSubmit={e => {
e.preventDefault();
this.props.onStart(parseInt(e.currentTarget.elements.number.value, 10));
}}>
Nb of posts to fetch<input type="number" name="number" placeholder="0"/>
<input type="submit" value="go"/>
</form>
}
</section>
);
}
componentWillMount () {
console.log("mounting");
}
}
非常简单:一种带有输入的表单,用于输入要执行的请求数(可以在表组件上选中复选框…)。
其道具如下:
componentWillUnmout
。它本身并不能做太多事情,所以让我们介绍一下recompose
。其目的是通过HOC
增强
组件。在此示例中,我们将使用帮助器。mapPropsStream
注意:在此答案中,我可以交替使用stream /
Observable,但这在通常情况下不正确。流是一个Observable,operators
可将发射的值转换为新的Observable。
对于React组件,我们可以使用标准api来观察其道具:第一个在componentWillMount,然后在componentWillReceiveProps。我们还可以通过componentWillUnmount发出何时不再发出道具的信号。我们可以构建以下(大理石)图:(p1 --p2--..--pn--|
管道指示流的完成)。
增强程序代码发布在下面并带有注释。
需要理解的是,所有带有流的事物都可以像信号一样被接近:通过将所有事物建模为流,我们可以确保通过发送适当的信号,我们可以具有所需的行为。
export const enhance = mapPropsStream(prop$ => {
/*
* createEventHandler will help us generates the callbacks and their
* corresponding streams.
* Each callback invocation will dispatch a value to their corresponding
* stream.
*/
// models the requested number of requests
const { handler: onStart, stream: requestCount$ } = createEventHandler();
// models the *stop* signals
const { handler: onStop, stream: stop$ } = createEventHandler();
// models the number of completed requests
const completedRequestCount$ = requestCount$.map( n => {
// for each request, generate a dummy url list
const urls = Array.from({ length: n }, (_, i) => `https://jsonplaceholder.typicode.com/posts/${i + 1}` );
// this is the trick : we want the process to be aware of itself when
// doing the next operation. This is a circular invocation so we need to
// use a *proxy*. Note : another way is to use a *subject* but they are
// not present in __xstream__, plz look at RxJS for a *subject* overview
// and implementation.
const requestProxy$ = xs.create();
const count$ = requestProxy$
// a *reduce* operation to follow where we are
// it acts like a cursor.
.fold(( n ) => n + 5, 0 )
// this will log the current value
.debug("nb");
const request$ = count$.map( n => Promise.all(urls.slice(n, n + 5).map(u => fetch(u))) )
.map(xs.fromPromise)
.flatten()
.endWhen(xs.merge(
// this stream completes when the stop$ emits
// it also completes when the count is above the urls array length
// and when the prop$ has emitted its last value ( when unmounting )
stop$,
count$.filter(n => n >= urls.length),
prop$.last()
));
// this effectively activates the proxy
requestProxy$.imitate(request$);
return count$;
} )
.flatten();
// models the processing props,
// will emit 2 values : false immediately,
// true when the process starts.
const processing$ = requestCount$.take(1)
.mapTo(true)
.startWith(false);
// combines each streams to generate the props
return xs.combine(
// original props
prop$,
// completed requests, 0 at start
completedRequestCount$.startWith(0),
// boolean indicating if processing is en route
processing$
)
.map(([ props, completedRequests, processing ]) => {
return {
...props,
completedRequests,
processing,
onStart,
onStop
};
})
// allows us to catch any error generated in the streams
// very much equivalent to the new ErrorBoundaries in React
.replaceError( e => {
// logs and return an empty stream which will never emit,
// effectively blocking the component
console.error(e);
return xs.empty();
} );
});
export const Answer = enhance(AnswerView);
我希望这个答案不会太过复杂,随时问任何问题。
附带说明一下,经过一番研究,您可能会注意到processing
逻辑中并没有真正使用布尔值,而只是用来帮助UI知道发生了什么:这比将状态附加到状态表上要干净得多this
。一个组件。
当技能处于开发阶段时,我可以在开发控制台中调用它。在Echo或Amazon Alexa应用程序中,该技能无法调用。 技能在技能之下显现 有人知道如何解决这个问题吗?
要在控制台应用程序中开始使用Hangfire,您需要首先将Hangfire包安装到控制台应用程序。因此,使用您的软件包管理器控制台窗口进行安装: PM> Install-Package Hangfire.Core 然后添加任务存储安装所需的软件包。例如,使用SQL Server: PM> Install-Package Hangfire.SqlServer 仅需 Hangfire.Core 软件包
我们正在升级一个J2EE应用程序(JSP 日志中显示以下内容: 应用程序确实安装(State=“Installed”),但无法启动。如果我们删除并重新安装它,则不会发生错误,其状态为“活动”,我们可以测试应用程序。然而,当服务器重新启动时,上述异常会出现在日志中,并且应用程序处于“ADMIN”状态。它无法启动,因此我们将其删除,并通过管理控制台重新安装,然后运行它,让我们对其进行测试。 应用程序中
问题内容: 我有两个MVC网站。站点1的控制器使用以下代码调用站点2 我可以直接浏览URL并查看JSON。但是从MVC中的对等网站下载JSON的正确方法是什么? 问题答案: 你或许应该把控制器方法为方法和用途,以避免死锁。 Microsoft的ASP.NET教程包括有关ASP.NET MVC 4中异步方法 的页面。
到目前为止,我认为我已经掌握了async await如何使应用程序更具响应性的概念,但我有两点悬而未决: 层注意事项异步等待是否必须从存储库层一直到MVC或WCF层才能获得性能优势,或者我可以只对需要很长时间的存储库方法进行异步操作吗? “等待”用法如果我只能在存储库级别工作,有一部分我不明白。使用这种(低层)方法,线程能够在等待io绑定代码完成的同时为传入的客户端请求提供服务吗? 在我看来,当长
没有await并且在非异步方法中调用异步方法的行为是什么?我这样问是因为我看到Visual Studio在调用异步方法时没有显示任何警告,好像这是一件非常正常的事情。在这种情况下,异步方法的行为是否像是同步的?