Promise与Async/await函数都是用来解决JavaScript中的异步问题的,那么它们之间有什么区别吗?下面本篇文章就来给大家介绍一下Promise、Generator和Async间的差异,希望对大家有所帮助!
|
Promise与Async/await函数都是用来解决JavaScript中的异步问题的,那么它们之间有什么区别吗?下面本篇文章就来给大家介绍一下Promise、Generator和Async间的差异,希望对大家有所帮助!
我们知道 异步解决方案的发展历程1.回调函数 从早期的Javascript代码来看,在ES6诞生之前,基本上所有的异步处理都是基于回调函数函数实现的,你们可能会见过下面这种代码: ajax('aaa', () => {
// callback 函数体
ajax('bbb', () => {
// callback 函数体
ajax('ccc', () => {
// callback 函数体
})
})
})没错,在ES6出现之前,这种代码可以说是随处可见。它虽然解决了异步执行的问题,可随之而来的是我们常听说的回调地狱问题:
所以,为了解决这个问题,社区最早提出和实现了 2.Promise Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它就是为了解决回调函数产生的问题而诞生的。 有了 所以上面那种回调函数的方式我们可以改成这样:(前提是ajax已用Promise包装) ajax('aaa').then(res=>{
return ajax('bbb')
}).then(res=>{
return ajax('ccc')
})通过使用 但Promise也有它的缺点:
let pro
try{
pro = new Promise((resolve,reject) => {
throw Error('err....')
})
}catch(err){
console.log('catch',err) // 不会打印
}
pro.catch(err=>{
console.log('promise',err) // 会打印
})
之前写过一篇,讲解了Promise如何使用以及内部实现原理。对Promise还不太理解的同学可以看看~
3.Generator
声明 与函数声明类似,不同的是 function* gen(x){
const y = yield x + 6;
return y;
}
// yield 如果用在另外一个表达式中,要放在()里面
// 像上面如果是在=右边就不用加()
function* genOne(x){
const y = `这是第一个 yield 执行:${yield x + 1}`;
return y;
}执行 const g = gen(1);
//执行 Generator 会返回一个Object,而不是像普通函数返回return 后面的值
g.next() // { value: 7, done: false }
//调用指针的 next 方法,会从函数的头部或上一次停下来的地方开始执行,直到遇到下一个 yield 表达式或return语句暂停,也就是执行yield 这一行
// 执行完成会返回一个 Object,
// value 就是执行 yield 后面的值,done 表示函数是否执行完毕
g.next() // { value: undefined, done: true }
// 因为最后一行 return y 被执行完成,所以done 为 true调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是 所以上面的回调函数又可以写成这样: function *fetch() {
yield ajax('aaa')
yield ajax('bbb')
yield ajax('ccc')
}
let gen = fetch()
let res1 = gen.next() // { value: 'aaa', done: false }
let res2 = gen.next() // { value: 'bbb', done: false }
let res3 = gen.next() // { value: 'ccc', done: false }
let res4 = gen.next() // { value: undefined, done: true } done为true表示执行结束由于 Generator 函数返回的遍历器对象,只有调用 遍历器对象的 (1)遇到 (2)下一次调用 (3)如果没有再遇到新的 (4)如果该函数没有
怎么理解这句话?我们来看下面这个例子: function* foo(x) {
var y = 2 * (yield (x + 1));
var z = yield (y / 3);
return (x + y + z);
}
var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}
var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }由于 yield与return的区别 相同点:
区别:
4.Async/await
所以上面的回调函数又可以写的更加简洁了: async function fetch() {
await ajax('aaa')
await ajax('bbb')
await ajax('ccc')
}
// 但这是在这三个请求有相互依赖的前提下可以这么写,不然会产生性能问题,因为你每一个请求都需要等待上一次请求完成后再发起请求,如果没有相互依赖的情况下,建议让它们同时发起请求,这里可以使用Promise.all()来处理
async函数 async函数的返回值为Promise对象,所以它可以调用then方法 async function fn() {
return 'async'
}
fn().then(res => {
console.log(res) // 'async'
})await表达式 await 右侧的表达式一般为 promise 对象, 但也可以是其它的值
function fn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1000)
}, 1000);
})
}
function fn1() { return 'nanjiu' }
async function fn2() {
// const value = await fn() // await 右侧表达式为Promise,得到的结果就是Promise成功的value
// const value = await '南玖'
const value = await fn1()
console.log('value', value)
}
fn2() // value 'nanjiu'异步方案比较后三种方案都是为解决传统的回调函数而提出的,所以它们相对于回调函数的优势不言而喻。而
说了这么多,顺便看个题吧~console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')解析: 打印顺序应该是: 老规矩,全局代码自上而下执行,先打印出 解题技巧:
【相关推荐:javascript学习教程】 以上就是浅析Promise、Generator和Async间的差异的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |
