我怎样才能实现模式承诺/延期?

Mul*_*tix 31 c# promise

我想写一个Promise/Deffered模式.完美的变体到底是:

MyObject().CallMethodReturningPromise()
   .done( result => {
       ...something doing;
   } )
   .fail( error => {
       ...error handle;
   } )
   .always( () => {
       ...some code;
   } )
Run Code Online (Sandbox Code Playgroud)

我发现了这个实现https://bitbucket.org/mattkotsenas/c-promises/overviewhttps://gist.github.com/cuppster/3612000.但是我怎么能用它来解决我的任务?

Ben*_*aum 48

C#用Tasks 解决了这个问题

任务解决了与JavaScript中的承诺相同的问题 - 您可以类似地使用它们.但通常情况下,你不应该.

有几个不同之处:

  • 任务已内置取消.
  • 任务并非总是启动,您可以拥有任务并在以后启动它们.
  • Promise执行同化,你不能拥有,Promise<Promise<T>>但你可以在C#中执行任务,并且可能需要调用.Unwrap任务.
  • TPL(任务并行化库)中有一个规范的任务实现,它随C#一起提供,但JavaScript中的许多promises实现.

使用任务

以下是如何将它们与async/await语法结合使用 - 这些语法将添加到ES7中的JavaScript中,并可yield在某些库中与ES6一起使用.

async Task Foo(){
    try{
        var res = await myObject.CallMethodReturningTaskOrAsyncMethod();
        doSomethingWithResponse(res);
    } catch(e){
         // handle errors, this will be called if the async task errors
    } finally {
        // this is your .always
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以使用.ContinueWith哪种相似之处,.then但它在C#中非常罕见,并且在等待可以使用时通常不赞成.您可以了解有关使用async/ awaithere的更多信息.

Deffereds被映射到TaskCompletionSource实例,Promises为TaskS IN C#.Task.WhenAll用于你使用$.when或的地方Promise.all.

你经常写的地方:

a().then(function(res){
    return b(res, "foo");
}).then(function(res2){
    // do work on res2
});
Run Code Online (Sandbox Code Playgroud)

你在C#中做了以下事情:

var res = await a();
var res2 = await b(res, "foo");
// do work on res2.
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下我如何处理错误? (3认同)
  • @Multix with try/catch,在C#中的异步函数中,你可以使用常规的try/catch并处理异步错误.使用`async/await`对于让您以同步方式编写异步代码非常有用.它是一个_really_强大的抽象,你真的很喜欢它来自JavaScript. (2认同)

Den*_*nis 28

在我看来,这非常适合任务:

var deferred = Task
    .Factory
    .StartNew(() => /* produce some result (promise) */);

// done
deferred
    .ContinueWith(d => Console.WriteLine(d.Result), TaskContinuationOptions.OnlyOnRanToCompletion);

// fail
deferred
    .ContinueWith(d => Console.WriteLine(d.Exception), TaskContinuationOptions.OnlyOnFaulted);

// always
deferred
    .ContinueWith(d => Console.WriteLine("Do something"));
Run Code Online (Sandbox Code Playgroud)