JavaScript async & await

版权声明:本文为simorel原创文章,未经simorel允许不得转载。 https://blog.csdn.net/Simoral/article/details/88633248

async & await


系列文章

这是JavaScript系列文章:



async

异步函数语句

async function

简介

定义一个返回 AsyncFunction 对象的异步函数。

  • async 函数内并不一定要有 await ,但是若存在 await , 则会等待 await 执行完毕的回调函数,再继续往下执行。

注意,await 只能出现在 async 函数内,否则会报错。

基础语法

async function name([params, [params, []]]) { statements }

  • name 函数名
  • params 参数
  • statements 函数体语句

示例

  1. 基础示例一

    function resolveAfter2Seconds() {
    	return new Promise(resolve => {
    		setTimeout(() => {
    			resolve('resolved');			
    		}, 2000);
    	});
    }
    
    async function asyncCall() {
    	console.log('calling');
    	let result = await resolveAfter2Seconds();
    	console.log(result);  // expected output: resolved
    }
    
    asyncCall();
    
  2. 示例二:使用 async 重构 promise

    • promise代码:

      function getProcessedData(url) {
      	return downloadData(url)  // 返回一个Promise对象
      		.catch(e => {
      			return downloadFallbackData(url);  // 返回一个Promise对象
      		})
      		.then(v => {
      			return processDataInWorker(v);  // 返回一个Promise对象
      		});
      }
      
    • async重构代码:
      为了避免await报错,所以这里使用 try...catch 来避免错误。

      async function getProcessedData(url) {
      	let v;
      	try {
      		v = await  downloadData(url);
      	}
      	catch (e) {
      		v = await downloadFallbackData(url);
      	}
      	return  processDataInWorker(v);
      }
      
  3. 示例三: 复杂示例

    var resolveAfter2Seconds = function() {
      console.log("starting slow promise");
      return new Promise(resolve => {
        setTimeout(function() {
          resolve("slow");
          console.log("slow promise is done");
        }, 2000);
      });
    };
    
    var resolveAfter1Second = function() {
      console.log("starting fast promise");
      return new Promise(resolve => {
        setTimeout(function() {
          resolve("fast");
          console.log("fast promise is done");
        }, 1000);
      });
    };
    
    var sequentialStart = async function() {
      console.log('==SEQUENTIAL START==');
    
      // 1. Execution gets here almost instantly
      const slow = await resolveAfter2Seconds();
      console.log(slow); // 2. this runs 2 seconds after 1.
    
      const fast = await resolveAfter1Second();
      console.log(fast); // 3. this runs 3 seconds after 1.
    }
    
    var concurrentStart = async function() {
      console.log('==CONCURRENT START with await==');
      const slow = resolveAfter2Seconds(); // starts timer immediately
      const fast = resolveAfter1Second(); // starts timer immediately
    
      // 1. Execution gets here almost instantly
      console.log(await slow); // 2. this runs 2 seconds after 1.
      console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
    }
    
    var concurrentPromise = function() {
      console.log('==CONCURRENT START with Promise.all==');
      return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
        console.log(messages[0]); // slow
        console.log(messages[1]); // fast
      });
    }
    
    var parallel = async function() {
      console.log('==PARALLEL with await Promise.all==');
      
      // Start 2 "jobs" in parallel and wait for both of them to complete
      await Promise.all([
          (async()=>console.log(await resolveAfter2Seconds()))(),
          (async()=>console.log(await resolveAfter1Second()))()
      ]);
    }
    
    // This function does not handle errors. See warning below!
    var parallelPromise = function() {
      console.log('==PARALLEL with Promise.then==');
      resolveAfter2Seconds().then((message)=>console.log(message));
      resolveAfter1Second().then((message)=>console.log(message));
    }
    
    sequentialStart(); // after 2 seconds, logs "slow", then after 1 more second, "fast"
    
    // wait above to finish
    setTimeout(concurrentStart, 4000); // after 2 seconds, logs "slow" and then "fast"
    
    // wait again
    setTimeout(concurrentPromise, 7000); // same as concurrentStart
    
    // wait again
    setTimeout(parallel, 10000); // truly parallel: after 1 second, logs "fast", then after 1 more second, "slow"
    
    // wait again
    setTimeout(parallelPromise, 13000); // same as parallel
    
    1. const xxx = await resolveFunction();
    2.  const xxx = resolveFunction();`
       console.log(await xxx); 
      
    3. 执行多个await函数
      return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
      	console.log(messages[0]); // slow
      	console.log(messages[1]); // fast
      });
      
    4. 同三,执行多个await函数,但是另一种写法
      await Promise.all([
      	(async()=>console.log(await resolveAfter2Seconds()))(),
        	(async()=>console.log(await resolveAfter1Second()))()
      ]);
      
    5. resolveAfter2Seconds().then((message)=>console.log(message));

异步函数表达式

async function expression

异步函数语句异步函数表达式 区别:
1. 异步函数表达式可以忽略函数名,创建一个匿名函数
2. 异步函数表达式可以立即执行

示例:

function resolveAfter2Seconds(x) {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve(x);
		}, 2000);
	});
}

let add1 = async function(x) {
	let a = await resolveAfter2Seconds(20);
	let b = await resolveAfter2Seconds(30);
	return x + a + b;
}

add1(10).then(v => {
	console.log(v);
});

// async function express
(async function(x) {
	let p_a = resolveAfter2Seconds(20);
	let p_b = resolveAfter2Seconds(30);
	return x + await p_a + await p_b;
})(10).then(v => {
	console.log(v);
});

await

  1. 简介

    • await 用于等待一个 Promise 对象,且只能在 async function 中使用。
    • await 会暂停当前函数执行,直到Promise执行完毕。然后继续往下执行。
  2. 基础语法
    [return_value] = await expression;

  3. 示例:若Promise处理异常,则异常值被抛出

    async function f3() {
      try {
        var z = await Promise.reject(30);
      } catch (e) {
        console.log(e); // 30
      }
    }
    f3();
    

参考链接

[1] MDN, async function
[2] MDN, async function expression
[3] MDN, AsyncFunction
[4] MDN, await
[5] 阮一峰, async 函数

感谢

猜你喜欢

转载自blog.csdn.net/Simoral/article/details/88633248