版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://cloud.tencent.com/developer/article/1347539
项目中有个需求,类似视频网站下载视频,比如有5个case,每个case有数量不等的的video需要从服务端下载,并且video的下载顺序是串联的,只有当正在下载的case下载完才能下载另外一个case,否则下一个case处于wait状态。
function downVideoSeries(n) {
if(n === 1) {
return new Promise((resolve, reject) =>{
//ajax code for one video
}).then((resolve)=>{
...
}).catch((err)=>{
...
})
}else if(n ===2) {
return new Promise((resolve, reject) =>{
//ajax code for one video
}).then((resolve)=>{
new Promise((resolve, reject) =>{
//ajax code for another video
})
}).then((resolve)=>{
...
}).catch((err)=>{
...
})
}
...
}
后经重新查看Promise,可以发现能构造一个空的Promise来解决问题,动画一帧帧执行的代码
function chainAnimationsPromise(elem, animations) {
// 变量ret用来保存上一个动画的返回值
let ret = null;
// 新建一个空的Promise
let p = Promise.resolve();
// 使用then方法,添加所有动画
for(let anim of animations) {
p = p.then(function(val) {
ret = val;
return anim(elem);
});
}
// 返回一个部署了错误捕捉机制的Promise
return p.catch(function(e) {
/* 忽略错误,继续执行 */
}).then(function() {
return ret;
});
}
async会将其后的函数(函数表达式或lamada)的返回值封装成一个Promise对象,所以获取async返回值用then调用。
async中的await用同步的方式来执行异步流,并且是阻塞的,只有当前的await执行,流程才会走向下一个。很适合此项目需求,因之前未用过,故配置webpack也遇到了坑。类似代码
async startDownPerCase() {
try{
for(let i=0; i<len; i++) {
let url = 'xhr.url';
//异步请求
await self.doBlobGet(url, ...args)
.then(()=>{
//成功回调
....
}).catch((err)=>{
//失败回调
...
});
}
} catch(e) {
console.log(`[downPerCaseError], ${e}`);
}
}
项目架构为webpack+react+es6。未配置的情况下,执行会输出错误提示Babel 6 regeneratorRuntime is not defined
,查阅stackoverflow,需要进行配置
presets: ['es2015', 'stage-3', 'react']
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
}
还有另外一种解决方案,使用 babel-plugin-transform-runtime
参考 https://stackoverflow.com/questions/33527653/babel-6-regeneratorruntime-is-not-defined
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。
返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
正常情况下,await命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象。
async function f() {
return await 123;
}
f().then(v => console.log(v))
// 123
只要一个await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。
async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}
所以一般会使用try catch来捕获错误
async function f() {
try {
await new Promise().then(()=>{}).catch(()=>{});
} catch(e) {
}
return await Promise.resolve('hello world');
}
如果有多个await命令,可以统一放在try…catch结构中。
async function main() {
try {
const val1 = await firstStep();
const val2 = await secondStep(val1);
const val3 = await thirdStep(val1, val2);
console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
async语法参考阮一峰大神写的http://es6.ruanyifeng.com/#docs/async#基本用法
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有