【前端入门】高效使用promise,通过并行&串行组合方式解决异步问题

53 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

回顾:前期关注“浏览器事件的执行限制”。Promise甚至还可以做更多的事情:若干个一步任务,如何不在写“一层层嵌套代码”的情况下,保障任何任务失败则不再继续并执行错误处理函数~让我们一起看看!

用Promise对象,简单处理串行执行异步任务

job1.then(job2).then(job3).catch(handleError);其中,job1job2job3都是Promise对象

直接看例题吧

// 0.5秒后返回input*input的计算结果:
function multiply(input) {
    return new Promise(function (resolve, reject) {
        log('calculating ' + input + ' x ' + input + '...');
        setTimeout(resolve, 500, input * input);
    });
}

// 0.5秒后返回input+input的计算结果:
function add(input) {
    return new Promise(function (resolve, reject) {
        log('calculating ' + input + ' + ' + input + '...');
        setTimeout(resolve, 500, input + input);
    });
}

var p = new Promise(function (resolve, reject) {
    log('start new Promise...');
    resolve(123);
});

p.then(multiply)
 .then(add)
 .then(multiply)
 .then(add)
 .then(function (result) {
    log('Got value: ' + result);
});

image.png

除了串行执行若干异步任务外,Promise还可以并行执行异步任务。两个任务是可以并行执行的。

例如:廖大神举例了一个聊天系统问题,需要从不同的url获取用户的个人信息和好友列表,这两个任务执行可以是并行的,分别不干扰。用Promise.all()实现如下:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
    console.log(results); // 获得一个Array: ['P1', 'P2']
});

特别地:多个异步任务是为了容错。例如上面的题目,我们向两个URL读取用户的个人信息,只需要获得先返回的结果即可无需两个都展示出来,结果效果是一样的。这种情况下,可以用Promise.race()实现:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
    console.log(result); // 'P1'
});

// 由于`p1`执行较快,Promise的`then()`将获得结果`'P1'`。`p2`仍在继续执行,最终执行结果将被丢弃

tips:组合使用Promise,即使再多的异步任务,也可以以并行和串行的方式组合起来执行哦~

写在最后

以上习题&笔记从大佬们的论坛学习而来,特感谢大佬们的知识分享~ (学习技术知识,果然要看大佬们的技术博客,大家有好的推荐也欢迎指引我这个小白哈,感恩!)

附上学习链接,感谢廖大神例题及分析参考 :www.liaoxuefeng.com/wiki/102291…