Javascript 基础之Promise

Noted:
Javscript 是一种单线程直译式的脚本语言,所有的代码都是单线程。由于它具备非阻塞式的特性,导致许多读写、网络等操作都需要回调函数。

//Snippet 1,
Post.getTen(null, page, function (err, posts, total) {
      if (err) {
        posts = [];
      } 
      ....
});

//Snippet 2,
Post.getTen = function(name, page, callback) {
  //打开数据库
  mongodb.open(function (err, db) {
    if (err) {
      return callback(err);
    }
    //读取 posts 集合
    db.collection('posts', function (err, collection) {
          var docs = [];
          var total = 10;
          callback(null, docs, total);
    });
  });
};

为了解决上面代码显示的问题,在ES6中做了一个统一规范Promise,从而优雅的回避了大量的回调函数。

可以在通过以下代码查看local的浏览器是否支持Promise的特性

'use strict';
new Promise(function () {alert('Support Promise!')});

Promise 实例,

//Snippet 1,
function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    setTimeout(function () {
        if (timeOut < 1) {
            resolve('200 OK');
        }
        else {
            reject('timeout in ' + timeOut + ' seconds.');
        }
    }, timeOut * 1000);
}

//Snippet 2,
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
    console.log('successd ' + result);
});
var p3 = p2.catch(function (reason) {
    console.log('failed ' + reason);
});

//Snippet 3,
new Promise(test).then(function (result) {
    console.log('successd ' + result);
}).catch(function (reason) {
    console.log('failed ' + reason);
}); 

Snippet 2 显示,
变量p1是一个Promise对象,它负责执行test函数。由于test函数在内部是异步执行的,当test函数执行成功时,我们告诉Promise对象。
当test函数执行失败时,我们告诉Promise对象。

Snippet 3 显示,
Promise对象可以串联起来,可见Promise 最大的好处就是在代码的执行过程中把执行的代码与处理结果的代码严格的分开了。

Promise 执行串行异步任务

要执行串行的异步任务任务,我们并不需要在写嵌套函数,只需要按照下面的格式:

job1.then(job2).then(job3).then(job4).catch(function (err) { console.log(err)});

// 0.5秒后返回input*input的计算结果:
function multiply(input) {
    return new Promise(function (resolve, reject) {
        console.log('multiply ' +input+ ' * ' +input);
        setTimeout(resolve, 500, input * input);
    });
}
// 0.8秒后返回input*input的计算结果:
function add(input) {
    return new Promise(function (resolve, reject) {
        console.log('add ' +input+ ' + ' +input);
        setTimeout(resolve, 800, input + input);
    });
}
var p = new Promise(function (resolve, reject) {
   console.log('start new Promise ... '); 
   resolve(2)
});

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

Promise 执行并行任务

Promise 也可以执行并行的任务,当我们的支付宝页面一方面要显示账户的余额,另外也要显示打折商家的信息。

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'balance');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 800, 'Detail Mes');
});

Promise.all([p1, p2]).then(function (results) {
    console.log(results)
}).catch(function (err) {
    console.log(err);
});

Promise 执行竞争任务

Promise 也可以实现多任务之间的竞争,比如抢红包。

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'balance');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 800, 'Detail Mes');
});

Promise.race([p1, p2]).then(function (results) {
    console.log(results)
}).catch(function (err) {
    console.log(err);
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 你不知道JS:异步 第三章:Promises 在第二章,我们指出了采用回调来表达异步和管理并发时的两种主要不足:缺...
    purple_force阅读 6,333评论 0 4
  • 异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...
    呼呼哥阅读 12,039评论 5 22
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 13,746评论 26 95
  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 7,636评论 0 5
  • 电话又响了、同事又来求助了、领导又叫你了,客户又找上门了......日常工作中,经常会遇到各种突发的状况,手...
    泥泥376阅读 2,241评论 0 0