饥人谷技术博客

ES6 promise——初探

2018-03-23  本文已影响6人  _贺瑞丰

本文思路

1.异步

JavaScript同步模式有如下特点:

2.ES5 异步实现

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);
}
//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什么时候使用

3.2 什么时候别用

常见用法

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以及各种静态文件。所有的都加载完后,我们再进行页面的初始化

上一篇 下一篇

猜你喜欢

热点阅读