async与await

#.net #javascript #async #await

async/await是一种新的语法,用同步的编程方式替换原有的回调函数和协程的用法.

.net中的async await

async

async 用于修饰方法, 方法的返回值必须是 void或者Task<T>. async的目的是:使方法内的await关键字生效。

await

await 仅可用于由 async 关键字修饰的异步方法中。如果没有async会报错. await修饰的方法, 返回值必须是Task. 如果要对普通调用使用await, 可以使用Task.Run(()=>{ method() })把方法包装成一个返回值为Task的匿名函数.

代码执行到await 标记的异步方法时, 主方法立即return, 之后的代码被阻塞,一直到异步方法完成,才会执行. 所以await, 相当于为本方法中 await之后的所有代码添加一个异步回调的任务.

async修饰的方法, 被调用时,

  • 不加await, 异步方法是异步执行, 异步方法后面的代码在当前线程中同步执行.
  • 加await, 异步方法是同步执行.

总结

异步可以提高响应能力。 异步不会阻塞线程 使用 async 来标记异步方法 使用 await 来指定暂停点,挂起其进度,在等待的异步过程完成后才能继续通过该点。同时,会将控制权返回至异步方法的调用方,调用方可以继续执行不依赖于异步返回结果的其它工作。 如果使用了 Async 最好一直使用它 异步方法避免使用 Task.Wait 和 Task.Result ,因为他们会导致死锁。

javascript中的async await

async

async 函数返回的是一个 Promise 对象. await 只能出现在 async 函数中 如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。 如果 async 函数没有返回值, 它会返回 Promise.resolve(undefined)。 async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await

await

一般来说,都认为 await 是在等待一个 async 函数完成。不过按语法说明,await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值

await 后面实际是可以接普通函数调用或者直接量的

如果一个函数本身就返回 Promise 对象,加 async 和不加 async 还是有一点点区别:加了 async 之后外面得到 Promise 对象并不是 return 的那一个.了解这一点后,如果我们需要在返回的 Promise 对象上附加一些东西,比如 cancel(),就得小心一点.

await 只能出现在 async 函数中, 在最外层方法中,不能用 await 获取其async方法返回值的情况下,我们当然应该用原来的方式:then() 链来处理这个 Promise 对象,就像这样:

testAsync().then(v => {
 console.log(v); // 输出 hello async
});

async修饰的方法, 被调用时:

  • 加await, 异步执行该方法, 立即return, 并把后续方法作为该异步方法的回调.
  • 不加await, 由于异步方法返回的是promise,所以此时会得到一个promise, 后续方法会立即同步执行.
async function print(){
    console.log("async print")
}

async function callAsync(){
    await print();
    console.log("1")
}

// 1. 不加await
// callAsync();
// console.log("2")
// output aysnc print  2 1


// 2. 加await,次数使用then代替
callAsync().then(v=>{
    console.log("2")
})
// output aysnc print  1 2

关于async方法中return的时机, 被async修饰的方法, 会在await行和它之前的代码会被同步执行并return, 之后的代码会被回调.

综合样例

console.log(1);
function fn1(){
    async function fn2(){
        async function async1(){ 
            console.log(2);
            await fn3();
            console.log(3);
        }

        function fn3(){ console.log(4); }
        await async1();
        new Promise(resolve => resolve(5)).then(res => console.log(res));
        console.log(6);
    }
    fn2();
    console.log(7);
}
fn1();
console.log(8);

//output 1 2 4 7 8 3 6 5