打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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函数中

}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
js 宏观任务和微观任务> promise的代码为什么比setTimeout先执行
vue使用promise、async、await的一点理解
异步解决方案----Promise与Await
JavaScript异步编程史:回调函数到Promise到Async/Await | Fundebug博客
原生Javascript使用Promise对象借助关键字async&await设置JS休眠时间
手写async await的最简实现(20行搞定)!阿里字节面试必考
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服