JS异步编程之generator与async/await语法糖详解
什么是异步编程?
通俗地讲,异步编程是指不需要等待上一个代码块执行完毕,就可以开始执行下一个代码块的编程方式。在JavaScript中,异步编程是常见的编程方式,它主要使用回调函数、Promise、Generator和async/await等语法来实现。其中,Generator和async/await都是基于Promise的编程方式,可以减少回调函数的嵌套,使异步代码逻辑更加清晰和易于维护。
Generator
Generator是ES6中引入的一种函数类型,使用关键字function*
来定义,它可以实现函数的暂停和继续执行,并且可以接收外部传入的值。其中,暂停和继续执行是通过yield
关键字实现的。下面是一个简单的Generator示例:
function* foo() {
console.log('start');
let value = yield 1;
console.log(value);
yield 2;
console.log('end');
}
let generator = foo();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next('hello')); // { value: 2, done: false }
console.log(generator.next()); // { value: undefined, done: true }
在上面的示例中,我们定义了一个Generator函数foo()
,它通过yield
关键字来实现了暂停和继续执行的功能。当我们执行generator.next()
时,Generator函数开始执行,并在第一次执行到yield 1
时暂停,返回一个包含value
和done
属性的对象{ value: 1, done: false }
。当我们再次执行generator.next('hello')
时,Generator函数从暂停的位置继续执行,并将'hello'
作为yield
表达式的返回值赋值给变量value
,然后打印出'hello'
。最后,Generator函数执行到末尾返回一个包含value
和done
属性的对象{ value: undefined, done: true }
。
async/await
async/await是ES2017中引入的一种异步编程方式,它可以让我们像编写同步代码那样编写异步代码,使代码更加易读易懂。其中,async关键字用于声明一个函数是异步的,必须返回一个Promise对象;await关键字用于等待一个Promise对象的执行结果,并返回执行结果。
下面是一个使用async/await的示例:
async function foo() {
console.log('start');
let value = await Promise.resolve('hello');
console.log(value);
console.log('end');
}
foo();
在上面的示例中,我们定义了一个async函数foo()
,它使用await
关键字等待一个Promise对象的执行结果。当我们执行foo()
时,函数开始执行,并在执行到await Promise.resolve('hello')
时暂停,等待Promise对象的执行结果。当Promise对象执行完毕后,await
关键字返回Promise对象的执行结果,将其赋值给变量value
,并打印出'hello'
。最后,函数执行结束并打印出'end'
。
示例说明
下面是一个使用Generator和async/await实现的异步编程示例:
function* generateSequence(start, end) {
for (let i = start; i <= end; i++) {
yield new Promise(resolve => setTimeout(() => resolve(i), 1000));
}
}
async function printSequence() {
const sequence = generateSequence(1, 5);
for await (let value of sequence) {
console.log(value);
}
}
printSequence();
在上面的示例中,我们定义了一个Generator函数generateSequence()
,它创建了一个包含Promise对象的生成器。其中,每个Promise对象都是通过setTimeout()
函数实现了一个1秒钟的延迟,并将当前值i作为Promise对象的执行结果。接着,我们定义了一个async函数printSequence()
,它使用for await...of
语法来迭代Generator对象sequence
,并异步打印出每个值。
输出结果为:
1
2
3
4
5
再举一个使用async/await解决回调函数嵌套问题的例子:
function getData() {
return new Promise(resolve => setTimeout(() => resolve('data'), 1000));
}
getData().then(data => {
console.log(data);
}).catch(error => {
console.error(error);
});
上面的代码使用Promise来异步获取数据,并使用.then()
和.catch()
来处理执行结果和异常情况。而使用async/await的方式可以使代码更加简洁和直观,如下所示:
async function getData() {
try {
const data = await new Promise(resolve => setTimeout(() => resolve('data'), 1000));
console.log(data);
} catch (error) {
console.error(error);
}
}
getData();
在上面的代码中,我们使用try...catch
语句来处理执行结果和异常情况。当然,async/await还支持使用.then()
和.catch()
来处理执行结果和异常情况。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS异步编程之generator与async/await语法糖详解 - Python技术站