async 和 await 之异步编程的学习

      async修改一个方法,表示其为异步方法。而await表示等待一个异步任务的执行。js方面,在es7中开始得以支持;而.net在c#5.0开始支持。本文章将分别简单介绍他们在js和.net中的基本用法。

一、在js中的实现

js中的异步,还是基于Promise实现的。没有Promise就办法谈异步了。并且await只能出现async修改的方法中;以及reject会触发catch(异常)。

class AsyncTest{
//simple example
    async run(){
//按照顺序等待后输出
let one = await this.output("one", 1000);
console.log('output:'   one);
let two = await this.output("two", 3000);
console.log(two);
console.log('run.....');
}
//await and Promise.all difference
    async runDiff(){ 
let one = this.output('diff one', 2000);
let two = this.output('diff two', 2000);
console.log(  await two   await one );  //在2秒之后,两个都输出了,而不是各自都等待两秒
console.log('runDiff.....');
}
//Promise.all realize
    runAll(){
let nowTime = new Date();
console.log('b:'   nowTime.toTimeString());
let array = ["a", "b", "c"];
let that = this;
array.forEach(async function(item){
console.log( await that.output(item, 2000) );//2秒后同时输出
        });
let fn = async ()=>{
for(let item of array){
let v = await this.output(item, 2000);
console.log(v ); //分步骤两秒执行
            }
}
fn.call(this);
}
premosFn(){
let nowTime = new Date();
console.log('b:'   nowTime.toTimeString());
let array = ["a", "b", "c"];
let that = this;
//promise.all
let preFn = async function(){
let promises = array.map(function(item){
return that.output(item,2000); //同时开启多个定时器
            });
let r = await Promise.all(promises);
console.log(r.join(','));
}
preFn();
}
reject(){
let rejectFn = function(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
reject();
},2000);
});
}
let asyncReject = async function(){
try{
await rejectFn();
}catch( e) {
console.log('reject.....');
}
}
asyncReject();
}
output(log, time){
return new Promise(resolve=>{
setTimeout(()=>{
var nowTime = new Date();
resolve( nowTime.toTimeString()   ":"   log   "\r\n");
}, time);
});
}
}

方法说明如下:

  • output:简单的输出方法,但返回了一Promise。
  • run: 使用await来等待两次对output的执行
  • runDiff:调用output时即创建promise。两个promise会同步执行
  • runAll:多任务同步执行和按步骤执行的实现方法。也就是forEach和for方法体中使用await的区别
  • premosFn: promise.all的使用。
  • reject: promise的reject会触发await的异常。

二、在c#中的实现

C#中异常是通过Task来实现的,所以标记了async的方法,其方法体中都可以出现await,否则不可以。以及Task中抛出的异常,如果没有同步等待,则不能获取异常

public class AsyncDemo
{
private Task<string> Output(string val, int time)
{
return System.Threading.Tasks.Task.Run(() =>
{
System.Threading.Thread.Sleep(time * 1000);
return (DateTime.Now.ToLongTimeString())   ": "   val   "\r\n";
});
}
public async System.Threading.Tasks.Task Run()
{
string oneVal = await Output("One", 2);
string twoVal = await Output("Two", 2);
System.Console.WriteLine("Run \r\n"   oneVal   " "   twoVal);
}
public async System.Threading.Tasks.Task RunDiff()
{
Task<string> oneTask = Output("one", 2);
Task<string> twoTask = Output("two", 2);
string val = await oneTask   await twoTask; 
System.Console.WriteLine("RunDiff \r\n"   val);
}
public async System.Threading.Tasks.Task RunAll()
{
System.Console.WriteLine("b:"   (DateTime.Now.ToLongTimeString()));
string[] array = new string[3] { "a", "b", "c" };
foreach(var item in array)
{
string v = await Output(item, 2);
System.Console.WriteLine(v);
}
}
public async System.Threading.Tasks.Task PromiseFn()
{
System.Console.WriteLine("b:"   (DateTime.Now.ToLongTimeString()));
string[] array = new string[3] { "a", "b", "c" };
List<System.Threading.Tasks.Task<string>> tasks = new List<System.Threading.Tasks.Task<string>>();
foreach (var item in array)
{
tasks.Add(Output(item, 2));
}
//waitAll返回值不能获取,他返回为void,而WhenAll则返回为一个Task(这个Task就有其列表值)
string[] r = await System.Threading.Tasks.Task.WhenAll(tasks.ToArray());
System.Console.WriteLine(string.Join(",",r));
}
public async System.Threading.Tasks.Task Reject()
{
Func<System.Threading.Tasks.Task> func = async () =>
{
throw new Exception("custom...");
await Output("reject", 2);
};
await func();
}
}

调用代码如下:

AsyncDemo asyncDemo = new AsyncDemo();
asyncDemo.Run().Wait();
asyncDemo.RunDiff().Wait();
asyncDemo.RunAll().Wait();
asyncDemo.PromiseFn().Wait();
try
{
asyncDemo.Reject().Wait();
}catch(Exception e)
{
System.Console.WriteLine("reject ex");
}

    上述代码就是Js的async和await在c#中的翻版实现。 其中每个异步方法的调用,都用到了Wait方法来进行同步等待。以获取到结果。而没有像Js中那么难以控制。尤其注意,async方法中异常的捕获。

三、两者的异同点

  • js中的async方法的调用,是没有wait方法来等待结果的执行的,只能通过promise来监听执行结果
  • c#中的async方法,由于推荐返回Task或者Task<T>,所以可以用Wait来等待执行结果,如果async方法返回为void,则与js类似。 C#中的下面示例方法的调用者捕获不了异常:
    public async void Run()
    {
    string oneVal = await Output("One", 2);
    string twoVal = await Output("Two", 2);
    System.Console.WriteLine("Run"   oneVal   " "   twoVal);
    }
  • c#中的Task可以异步方法的链式调用,即可将前一任务的执行结果作为第二任务的参数传入,当然js的Promise也完全是可以很轻松的实现:
System.Console.WriteLine("b:"   (DateTime.Now.ToLongTimeString()));
string[] array = new string[3] { "a", "b", "c" };
var r = await this.Output(array.First(), 2).ContinueWith((tsc) =>
{
string v = tsc.GetAwaiter().GetResult();
return this.Output(v   "02", 2);
});
System.Console.WriteLine(r.Result);

更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363665.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WinAPI: SetRect 及初始化矩形的几种办法

本例分别用五种办法初始化了同样的一个矩形, 运行效果图:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 class(TForm)Button1: TButton;Button2: TButton;Button3: TButton;Button4: TBu…

Eureka 集群高可用配置.

SERVER:1 server:port: 1111 eureka:instance:hostname: ${spring.cloud.client.ip-address}instance-id: ${eureka.instance.hostname}:${server.port}preferIpAddress: true #指定通过IP注册,一般服务集群时配置,需要ip-address参数一起设置(保证hostName和ip-address一…

备忘录——通过RVA计算文件位置

备忘录——通过RVA计算文件位置 原创&#xff1a;Anders Liu 摘要&#xff1a;本文介绍了如何通过PE文件中某一项的RVA来计算其在文件中的位置。 参考文献 ECMA-335——Common Language Infrastructure (CLI) 4th Edition, June 2006 范畴 该备忘录描述了在分析PE&#xff08;可…

使用Java 8的Builder模式

我在一个环境中工作&#xff0c;其中通过调用远程服务而不是使用数据库来执行大量日常脚本任务。 对于许多脚本编写任务&#xff0c;我经常使用Groovy&#xff0c;而Groovy专门用于该任务的最有用的功能之一就是它是用流畅的Builders构建的 。 现在&#xff0c;Groovy构建器利…

Asp.net2.0工具包AjaxControlToolkit下载和安装

Asp.net2.0工具包AjaxControlToolkit下载和安装:点击下载 环境设置如下&#xff1a;A!a.S-DQ0ITPUB个人空间P,JN2y2b o5K 下载完 ASPAJAXExtSetup.msi 安装更新后在你的系统盘下的&#xff08;以C盘为例&#xff09; 出现这个 文件夹&#xff1a;ITPUB个人空间nA*O2U/l8i69s#o0…

中后端管理系统前后分离、前端框架的实现拙见

一、实现思路 在实践中后台管理系统的前后端分离时&#xff0c;往往会因为业务量的增加使其前端项目难以维护&#xff0c;以及打包时间不理想&#xff0c;还有业务系统与框架之间区分不在明显。本文是本人从另一个角度提出的一种解决方案&#xff0c;希望各位提出宝贵的建议。…

初见mobX

先看如下的代码 const {observable} mobox; const {observer}mobxReact; const {Component}React; const appStateobservable({count:0 }) appState.incrementfunction(){this.count } appState.decrementfunction(){this.count-- } observer class Counter extends Component{…

html输入完账号密码才能跳转,HTML输入字段跳转

我有2个文本字段&#xff0c;用户名和密码。当我输入密码时&#xff0c;它跳到第一个。我不知道为什么会这样。我无法找到它为什么跳。如何更改密码表单不跳转&#xff1f;这里是代码&#xff1a;HTML输入字段跳转session_start();require_once database.php;if (isset($_SESSI…

让使用MSN就像访问网页一样容易!

有时候&#xff0c;你不得不佩服微软的想法&#xff01; http://webmessenger.msn.com/转载于:https://www.cnblogs.com/Hush/archive/2004/12/10/75430.html

学用状态机模式,写的报销流程,请指教

刚学编程不久&#xff0c;请前辈们指点。需求变化点&#xff1a;不同的金额&#xff0c;和不同的角色走不同的报销流程usingSystem;staticclassFactory { publicstaticEmployee CreateEmployee(stringname) { Employee employee null; switch(name) …

Java 8 Friday:更好的异常

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 Java 8星期五 每个星期五&#xff0c;我们都会向您展示一些不错的教程风格的Java 8新功能&#…

【留言板】可编辑输入框操作总结

闲暇之余&#xff0c;用于加深自己对基础的了解&#xff0c;徒手撸了一个留言板&#xff1a;输入框。废话少说&#xff0c;进入正题。简陋的效果如下(下载代码)&#xff1a; 一、定义需求 可输入文本&#xff0c;以及插入表情。兼容性&#xff1a;IE与标准浏览器 二、详细设计…

excel poi3.17导出导入

https://blog.csdn.net/phil_jing/article/details/78307819 转载于:https://www.cnblogs.com/lyon91/p/10450668.html

2021年兰州师大附中高考成绩查询,2021年兰州重点高中名单及排名,兰州高中高考成绩排名榜...

”一千个人眼中&#xff0c;就有一千个哈姆雷特“。关于兰州高职学校排名&#xff0c;每个人的观点也是各不相同&#xff0c;今天就给大家分享一下我心中的兰州高中排名及格局分布&#xff0c;主要参考依据是近年中考录取分数线及高考成绩。数据仅供参考&#xff01;希望对你有…

Android 创建,验证和删除桌面快捷方式 (删除快捷方式测试可用)

测试环境为Adnroid 2.1以上。 第一步&#xff1a;AndroidManifest.xml 权限配置&#xff1a; 添加快捷方式权限&#xff1a; <uses-permission android:name"com.android.launcher.permission.INSTALL_SHORTCUT"/> 验证快捷方式是否存在权限&#xff1a; <u…

ASP.NET存储Session的StateServer

由于公司要对服务器做个负载均衡&#xff0c;所以Web项目在两台前端服务器(web1、web2)各部署了一份。但是在项目中会用到session。当一开始在web1上登陆后&#xff0c;由于web1之后负载可能会变大&#xff0c;就有可能从web1跳转到web2上。从网上找了好多资料&#xff0c;自己…

休眠和UUID标识符

介绍 在我以前的文章中&#xff0c;我谈到了UUID代理密钥以及用例 &#xff0c; 这些用例比更常见的自动增量标识符更合适。 UUID数据库类型 有几种方法可以表示128位UUID&#xff0c;并且每当有疑问时&#xff0c;我都希望向Stack Exchange寻求专家建议。 由于通常对表标识符…

use vue vuex vue-router, not use webpack

vue,vuex,vue-router放在一起能做什么&#xff1f;不用webpack之类的打包工具使用他们是否可行&#xff1f;各位道友在初学vue时是否有这样的困惑。因为现代构建前端项目的一般模式是&#xff1a; 安装webapck&#xff0c;某种是glup,grunt&#xff0c;或者是fis等构建工具然后…

html网页加入一个按钮,在html网页设计中,一个“登录”按钮怎么编写代码?

html网页设计&#xff1a;一个简单的登录界面代码&#xff01;在html网页设计中&#xff0c;一个“登录”按钮怎么编写代码&#xff1f;列如所给图片的“登录”按钮怎么用html代码显示出来&#xff0c;要求能够识别是否输入用户名和密码&#xff01;是这样的效果吗&#xff1f;…

blender的汉化方法!

本人对于此只是初步认知阶段&#xff0c;也许对于电脑高手来说&#xff0c;这只是小儿科。但对于我来说&#xff0c;能够摸索出其中的方法&#xff0c;还是费了一些力气&#xff0c;所以&#xff0c;也蛮有成就感。希望拿来与同是处于初学水平的朋友共同学习。 blender这个软件…