ES6新特性(5)之Promise/async
目录
(一)Promise
传统实现异步操作就是采用回调函数,回调函数方式本身没有什么问题,但是在多重回调层层嵌套的情况下,那么代码的可阅读性就会出现问题。
Promise对象是一个新的异步操作解决方案,比原有的回调函数等方式更为合理
Promise对象具有三种状态:Pending(等待)、Resolved(已完成)和Rejected(未完成)。
Promise对象状态的改变只有两种可能:Pending转变为Resolved或者Pending转变为Rejected。
-
step1().then(step2).then(step3).then(step4).catch(function(err){
-
-
// do something when err
-
-
});
例:
-
let param; //传递参数载体
-
-
function p1() {
-
-
return new Promise(function(resolve, reject) {
-
-
//异步操作
-
-
setTimeout(function() {
-
-
console.log("aaaaa");
-
-
//resolve(123);
-
-
param = '第1';
-
-
reject(123);
-
-
}, 3000);
-
-
});
-
-
}
-
-
-
-
function p2() {
-
-
return new Promise(function(resolve, reject) {
-
-
setTimeout(function() {
-
-
console.log("bbbbb");
-
-
param = '第2';
-
-
resolve(456); //继续向下
-
-
//reject(456); //截停
-
-
}, 2000);
-
-
});
-
-
}
-
-
-
-
function p3() {
-
-
return new Promise(function(resolve, reject) {
-
-
setTimeout(function() {
-
-
console.log("cccccc");
-
-
console.log('传来:' + param);
-
-
param = '第3';
-
-
resolve(789);
-
-
}, 500);
-
-
});
-
-
}
-
-
-
-
function p4() {
-
-
return new Promise(function(resolve, reject) {
-
-
setTimeout(function() {
-
-
console.log("dddddd");
-
-
console.log('传来:' + param);
-
-
resolve('结束');
-
-
}, 1000);
-
-
});
-
-
}
-
-
-
-
p1().then(p2).then(p3)
-
-
.then(function(data) {
-
-
console.log('data: ' + data);
-
-
})
-
-
.catch(function(error) {
-
-
console.log('end,error: ' + error);
-
-
if(error == 123) { //如果第1步出错
-
-
p3().then(p4);
-
-
} else if(err == 456) {
-
-
p4();
-
-
}
-
-
});
输出-------------------------------------:
(二)async
Async/Await应该是目前最简单的异步方案了,ES7 中新增了 async/await 两个关键词。async 可以声明一个异步函数,此函数需要返回一个 Promise 对象。await 可以等待一个 Promise 对象 resolve,并拿到结果。
一个栗子:
-
var sleep = function (time) {
-
-
return new Promise(function (resolve, reject) {
-
-
console.log('执行');
-
-
setTimeout(function () {
-
-
resolve();
-
-
}, time);
-
-
})
-
-
};
-
-
-
-
var start = async function () {
-
-
// 在这里使用起来就像同步代码那样直观
-
-
console.log('start');
-
-
await sleep(3000);
-
-
console.log('end');
-
-
};
-
-
-
-
start();
async 表示这是一个async函数,await只能用在这个函数里面。
await 表示在这里等待promise返回结果了,再继续执行。
await 后面跟着的应该是一个promise对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了)
获得返回值
await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。
-
var sleep = function (time) {
-
-
return new Promise(function (resolve, reject) {
-
-
setTimeout(function () {
-
-
// 返回 ‘ok’
-
-
resolve('ok');
-
-
}, time);
-
-
})
-
-
};
-
-
-
-
var start = async function () {
-
-
let result = await sleep(3000);
-
-
console.log(result); // 收到 ‘ok’
-
-
};
捕捉错误
既然.then(..)不用写了,那么.catch(..)也不用写,可以直接用标准的try catch语法捕捉错误。
-
-
var sleep = function (time) {
-
-
return new Promise(function (resolve, reject) {
-
-
setTimeout(function () {
-
-
// 模拟出错了,返回 ‘error’
-
-
reject('error');
-
-
}, time);
-
-
})
-
-
};
-
-
-
-
var start = async function () {
-
-
try {
-
-
console.log('start');
-
-
await sleep(3000); // 这里得到了一个返回错误
-
-
-
-
// 所以以下代码不会被执行了
-
-
console.log('end');
-
-
} catch (err) {
-
-
console.log(err); // 这里捕捉到错误 `error`
-
-
}
-
-
};
循环多个await
await看起来就像是同步代码,所以可以理所当然的写在for循环里,不必担心以往需要闭包才能解决的问题。
..省略以上代码
-
-
var start = async function () {
-
-
for (var i = 1; i <= 10; i++) {
-
-
console.log(`当前是第${i}次等待..`);
-
-
await sleep(1000);
-
-
}
-
-
};
值得注意的是,await必须在async函数的上下文中的。
..省略以上代码
-
let 一到十 = [1,2,3,4,5,6,7,8,9,10];
-
-
// 错误示范
-
-
一到十.forEach(function (v) {
-
-
console.log(`当前是第${v}次等待..`);
-
-
await sleep(1000); // 错误!! await只能在async函数中运行
-
-
});
-
-
-
-
// 正确示范
-
-
for(var v of 一到十) {
-
-
console.log(`当前是第${v}次等待..`);
-
-
await sleep(1000); // 正确, for循环的上下文还在async函数中
-
-
}
文章来源: zhulin1028.blog.csdn.net,作者:zhulin1028,版权归原作者所有,如需转载,请联系作者。
原文链接:zhulin1028.blog.csdn.net/article/details/123972927
- 点赞
- 收藏
- 关注作者
评论(0)