本篇内容主要讲解“js怎么实现异步串行与异步并行”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“js怎么实现异步串行与异步并行”吧!
串行:这个就像队列一样,一个执行完,下一个再执行,比如js同步执行
并发:是指这个系统拥有处理多个任务的能力,在一定时间发出,不需要同时性执行。js的异步消息队列让js拥有并发的能力
比如执行多个settimeout 它会挂载在消息队列,然后依次执行
并行:是指这个系统拥同时处理多个任务的能力,属于多线程的一种方式,而js是属于单线程 虽然可以通过worker来创建多线程,但是子线程
完全受主线程控制,没有改变JavaScript单线程的本质
串行示意图:
有人会问,异步不是都在消息队列吗,不就是一个一个执行了吗?
举个例子,如果本身就是串行执行,那么你现在执行2给个任务,一个是5秒后打印console.log(1),一个是十秒后打印console.log(2)
按照串行应该是15秒执行完毕,但实际耗时是10秒,如上这是并发,
console.time() setTimeout(() => { console.log(1) }, 5000); setTimeout(() => { console.log(2) console.timeEnd() }, 10000);
大多时候我们可以用 promise 和async await来解决
promise
比较少的时候,可以用.then来实现串行
var a = function() { return new Promise((resolve, reject) => { setTimeout(() => { consloe.log('a') resolve('a') }, 3000) }) } var b = function() { return new Promise((resolve, reject) => { setTimeout(() => { consloe.log('b') resolve('b') }, 2000) }) }; console.time('test') a().then((aa) => { b().then((bb) => { console.log(`${aa}-${bb}`) console.timeEnd('test') }) })
async await
我们改造一下,明显使用await看起来更加清晰
var a = function() { return new Promise((resolve, reject) => { setTimeout(() => { consloe.log('a') resolve('a') }, 3000) }) } var b = function() { return new Promise((resolve, reject) => { setTimeout(() => { consloe.log('b') resolve('b') }, 2000) }) }; (async () => { console.time('test') var aa = await a() var bb = await b() console.log(`${aa}-${bb}`) console.timeEnd('test') })()
但当我们有多个异步,比如2000个该如何
var createPromise = function(time) { // then中的回调函数 return (resolve, reject) => { return new Promise((resolve, reject) => { setTimeout(() => { //模拟请求 (真实使用把time设置为0,将resolve传入异步函数中) console.log('timein' + time) resolve(); //在异步处理结束后resolve }, time * 1000) }) } } var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)]; function serpromise(arr) { arr.reduce((pre, next, index, carr) => { return pre.then(next) }, Promise.resolve()) } // 相当于 // Promise.resolve().then(createPromise(2)).then(createPromise(1))...... serpromise(arr)
async await
var createPromise = function(time) { return () => { return new Promise((resolve, reject) => { setTimeout(() => { //模拟请求 (真实使用把time设置为0,将resolve传入异步函数中) console.log('timein' + time) resolve(); //在异步处理结束后resolve }, time * 1000) }) } } var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)]; var fn = async function(promiseArr) { for (let i = 0, len = arr.length; i < len; i++) { let currentPromise = promiseArr[i] var result = await currentPromise() } } fn(arr)
通过打印可以看出如过是并发的打印会是1,2,3,4,5
并行示意图:
js并不能并行,我们只是可以思考如何卡在abc都执行完成,这里可以用promise.all 来轻松实现
const a = new Promise((resolve, reject) => { //模拟异步任务 setTimeout(function() { resolve('a'); }, 1000) }) .then(result => result) .catch(e => { }) const b = new Promise((resolve, reject) => { setTimeout(function() { // resolve('b'); reject('Error in b'); }, 1000) }) .then(result => result) .catch(e => e) Promise.all([a, b]).then(data => { console.log('data', data) }) .catch(e => console.log('erro', e));
这里需要注意的是,all能接受的 resolve reject都行,所以需要每个自己去处理异常
多个异步
promise
var createPromise = function(time) { return new Promise((resolve, reject) => { setTimeout(() => { console.log('time', time); resolve(time) }, time * 1000) }) } var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)]; Promise.all(arr).then(data => { console.log('data', data) })
asnyc await
var createPromise = function(time) { return new Promise((resolve, reject) => { setTimeout(() => { console.log('time', time); resolve(time) }, time * 1000) }) } var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)]; var fn = async function(promiseArr) { let awaitArr = [] for (let i = 0, len = arr.length; i < len; i++) { let currentPromise = promiseArr[i] let result = await currentPromise awaitArr.push(result) } return awaitArr } // async 返回的是一个promise fn(arr).then(data => { console.log('data', data); })
到此,相信大家对“js怎么实现异步串行与异步并行”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。