ES6 promise——初探

本文思路

    1. 什么是异步
    1. ES5异步实现方案
    1. ES6 promise解决了什么问题
    1. promise应该如何使用

1.异步

JavaScript同步模式有如下特点:

  • 1个:解释执行JavaScript代码的线程
  • 顺序:代码必须从上到下依次执行
  • 缺点:某代码片段执行很久,造成阻塞。
    JavaScript异步模式:
  • 新增任务队列
    主线程仍由上到下执行,需要异步操作,则将操作新增到任务队列,主线程优先执行,然后在是任务队列,任务队列中遵守:消息队列,事件循环
    保证了主要代码的迅速执行,异步操作在另外的地方去依次排队
  • 回调函数
    主线程需要发起异步,发起异步的函数一般为注册函数,其内部包含异步操作封装为callback(回调函数)
  • 现实例子
    在公路上,汽车一辆接一辆,有条不紊的运行。这时,有一辆车坏掉了。假如它停在原地进行修理,那么后面的车就会被堵住没法行驶,交通就乱套了。幸好旁边有应急车道,可以把故障车辆推到应急车道修理,而正常的车流不会受到任何影响。等车修好了,再从应急车道回到正常车道即可。唯一的影响就是,应急车道用多了,原来的车辆之间的顺序会有点乱。

2.ES5 异步实现

  • setTimeout + callback
function fn1ForLongTime(callback){}
function fn2ForShortTime(callback){}

将时间长的fn1改为异步,f2写成f1的回调函数

function fn1ForLongTime(callback){
  setTimeout(function(){
     //下面写f1的代码
     callback()
  },1000)
}
function fn2ForLongTime(){}
fn1ForLongTime(fn2ForLongTime)

执行顺序为:fn1发起异步,等fn1执行完毕后,再执行fn2.
形如f1(f2),而实际的f1代码与f2混在一起,能否支持f1(f2,f3)?
如果采用不停嵌套的方式来实现f1(f2,f3),代码可读性很差。

  • 事件监听
    容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
    整个程序都要变成事件驱动型,运行流程会变得很不清晰··
f1.on('done', f2);
function f1(){
 setTimeout(function () {
  // f1的任务代码
    
   f1.trigger('done');
 }, 1000);
}
  • 发布订阅模式
    在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做["发布/订阅模式"]
//f2收到done的信号就可以继续
jQuery.subscribe("done", f2);
function f1(){
    setTimeout(function () {
      // f1的任务代码

      jQuery.publish("done");
    }, 1000);
  }

我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

3.Promise是什么

Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口
每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。
作用:
(1)简化回调写法
(2)链式操作

3.1什么时候使用

  • One-and-Done Operations

    • Asynchronous I/O operations: methods to read or write from a storage API could return a promise.
    • Asynchronous network operations: methods to send or receive data over the network could return a promise.
    • Long-running computations: methods that take a while to compute something could do the work on another thread, returning a promise for the result.
    • User interface prompts: methods that ask the user for an answer could return a promise.
  • One-Time "Events"
    因为promise对象提供了
    pending:初始状态,也称为未定状态,就是初始化Promise时,调用executor执行器函数后的状态。fulfilled:完成状态,意味着异步操作成功。rejected:操作失败;
    a resource such as an image, font, or even document, could provide a loaded property that is a promise that becomes fulfilled only when the resource has fully loaded (or becomes rejected if there’s an error loading the resource). Then, authors can always queue up actions to be executed once the resource is ready by doing resource.loaded.then(onLoaded, onFailure). This will work even if the resource was loaded already,

  • More General State Transitions
    还没有研究

3.2 什么时候别用

  • Recurring Events
  • Streaming Data

常见用法

  • Promise构造函数
var p = new Promise(function(resolve, reject){
    //做一些异步操作
    setTimeout(function(){
        console.log('执行完成');
        resolve('随便什么数据');
    }, 2000);
});

我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,所以一般我们这么写:

function runAsync(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            resolve('随便什么数据');
        }, 2000);
    });
    return p;            
}
runAsync()

然后函数返回了promise对象,我们可以继续操作,在runAsync()的返回上直接调用then方法,then接收一个参数,是函数,并且会拿到我们在runAsync中调用resolve时传的的参数。运行这段代码,会在2秒后输出“执行完成”,紧接着输出“随便什么数据”。

runAsync().then(function(data){
    console.log(data);
    //后面可以用传过来的数据做些其他操作
    //......
});
//输出"执行完成" "随便什么数据"
runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});

then可以有两个参数

function getNumber(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            var num = Math.ceil(Math.random()*10); //生成1-10的随机数
            if(num<=5){
                resolve(num);
            }
            else{
                reject('数字太大了');
            }
        }, 2000);
    });
    return p;            
}

getNumber()
.then(
    function(data){
        console.log('resolved');
        console.log(data);
    }, 
    function(reason, data){
        console.log('rejected');
        console.log(reason);
    }
);

all的用法

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});

用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。
一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,695评论 1 56
  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 2,693评论 0 5
  • Promise的含义:   Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和...
    呼呼哥阅读 2,158评论 0 16
  • 你不知道JS:异步 第三章:Promises 在第二章,我们指出了采用回调来表达异步和管理并发时的两种主要不足:缺...
    purple_force阅读 2,044评论 0 4
  • 武侠江湖 琊令第四十期:刀剑如梦 小刀和小剑是对孪生子,他们的父亲,是江湖第一铸造师。 从二子的名字上,就能看出铸...
    一之鱼阅读 433评论 7 6