zoukankan      html  css  js  c++  java
  • Promise的理解

    1,什么是Promise

    Promise对象用于异步操作,它表示一个尚未完成且预计在未来完成的异步操作。

    1.1,同步和异步的概念

    JavaScript的执行环境是单线程;

    所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程。

    但实际上还有其他线程,如事件触发线程、ajax请求线程等。

    1.1.1 同步

    同步模式,一次只能执行一个任务,函数调用后需要等到函数执行结束,

    返回执行结果,才能进行下一个任务。如果这个任务执行的时间较长。

    就会导致线程阻塞。

    var x = true;
    while(x);
    console.log("don't carry out"); //并不会执行这句

    while是一个死循环,它会阻塞进程,因此后面的console并不会执行。

    1.1.2 异步

    异步与同步模式相反,可以一起执行多个任务。函数的调用不会立马返回执行结果。

    如果A任务需要等待(如读取文件),可先执行B任务。等A任务结果返回再继续回调。

    setTimeout(function(){
       console.log('task A, asynchronous');
    },0);
    
    console.log('Task B, synchronous');
    
    
    -------output--------
    task B, ....
    task A, ....

    我们可以看到,定时器延时的时间明明是0,但是task A 还是比task B后执行。

    原因是定时器是异步的,异步任务会在同步任务执行完之后才会执行。

    因为同步任务阻塞了进程。

    1.1.3 回调函数

    异步,必须提到回调函数。

    setTimeout里面的function就是回调函数。

    可以理解为:执行完 调用的 函数。

    回调函数不仅可以用于异步调用,一般的同步场景也可以回调。

    同步:回调函数一般是最后执行;

    异步:一段时间后执行或者不执行(没有达到执行条件)。

    /*    同步回调   */
    var fun1 = function( callback){
        //do something
        console.log("before callback") ; 
      (callback && typeof(callback) === 'function') && callback();
        console.log("after callback");           
    }
    
    var fun2 = function (param){
        // do something
        var start = new Date();
        while( (new Date() - start) ) < 3000 {
        // delay 3000ms    
        }
        console.log("I‘am callback");
    }
    fun1(fun2);
    
    ------output-----
    before callback
    //after 3000ms
    I ' am callback
    //再执行同步回调
    after callback

    1.2 为什么使用Promise

    Promise是基于异步操作的。

    既然我们可以使用异步回调的进行异步操作,为什么还要使用Promise呢?

    function sendRequest(url , param){
        return new Promise(fiunctiuon (resolve,reject) {
             request (url , param, resolve, reject);
        });
    }
    
    
    sendRequest('test.html' , ' ' ).then (function(data) {
        //异步操作成功后回调
        console.log('请求成功,这是返回的数据:' , data);
    } function (error){
        //异步操作失败的回调
         console.log('sorry,请求失败了,这是失败信息:’) ,error);
    }
    );

    上述的Promise 的简单用法;

    我们可以看到Promise 的强大的之处是:多重链式调用;

    sendRequest('test1.html', '').then(function(data1) {
        console.log('第一次请求成功, 这是返回的数据:', data1);
        return sendRequest('test2.html', data1);
    }).then(function(data2) {
        console.log('第二次请求成功, 这是返回的数据:', data2);
        return sendRequest('test3.html', data2);
    }).then(function(data3) {
        console.log('第三次请求成功, 这是返回的数据:', data3);
    }).catch(function(error) {
        //用catch捕捉前面的错误
        console.log('sorry, 请求失败了, 这是失败信息:', error);
    });

    2.Promise的基本用法

    2.1 基本用法

    promise对象代表一个未完成,但预计将来会完成的操作。

    promise的三种状态:

      1. pending : 初始值,不是fulfilled,也不是rejected

      2. fulfilled :  代表操作成功

      3. 代表操作失败

    Promise 有两种状态改变的方式,既可以从pending 转变成fulfilled,

    也可以从pending 转变成rejected.一旦状态发生改变。就不再发生变化。

    之后执行 promise.then绑定的函数。

    * : Promise 一旦新建就会立即执行,无法取消。这也是它的缺点之一。

    var promise =  new Promise ( function (resolve, reject ) {
        if (/* 异步操作成功 */){
              resolve(data);
        }else{
           /* 异步操作失败 */
           rejected (error);
        }
    })

    使用new 关键字构建 Promise。

    Promise 接受一个函数作为参数,函数的两个参数分别是 resolve,rejected

    这两个函数就是回调函数,由JavaScript引擎提供。

    resolve 函数的作用: 再异步操作成功时调用,并将异步操作,作为参数传递出去;

    rejected 函数的作用: 再异步操作失败时调用,并将异步操作,作为参数传递出去;

    Promise实例生成以后,可以用then方法指定resolve状态和reject状态的回调函数。

     1 var promise = new Promise(function (resolve, reject) {
     2     if (/* 异步操作成功 */) {
     3         resolve(data);
     4     } else {
     5         /* 异步操作失败 */
     6         reject(error);
     7     }
     8 });
     9 
    10 promise.then( onFulfilled, onRejected);
    11  
    12 promise.then(function(data) {
    13     //do something when success
    14 }.function (error) {
    15     //do something when failure 
    16 });

    2.2 基本API

    .then ()

    语法:Promise.prototype.then( onFulfilled, onRejected)

    对promise添加onFulfilled 和 onRejected回调

    并返回一个新的Promise实例。

    且返回值作为参数传入新的promise的resolve函数。

    .catch ()

    语法:Promise.prototype.catch( onRejected)

    该方法是.then ( undefined, onRejected)的别名,用于指定发生错误时的回调函数。

     1 promise.then(function(data) {
     2     console.log('success');
     3 }).catch(function(error) {
     4     console.log('error', error);
     5 });
     6 
     7 /*******等同于*******/
     8 promise.then(function(data) {
     9     console.log('success');
    10 }).then(undefined, function(error) {
    11     console.log('error', error);
    12 });

    reject方法的作用,等同于抛错。

    .all ()

    语法:Promise.all( iterable)

    该方法用于多个promise实例,包装成一个新的promise实例

    1 var p = Promise.all( [p1,p2,p3] )

    Promise.all方法接受一个数组(或具有Iterator接口)作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定。

    • 当p1, p2, p3状态都变为fulfilled,p的状态才会变为fulfilled,并将三个promise返回的结果,按参数的顺序(而不是 resolved的顺序)存入数组,传给p的回调函数,如例3.8。
    • 当p1, p2, p3其中之一状态变为rejected,p的状态也会变为rejected,并把第一个被reject的promise的返回值,传给p的回调函数,

    .race ()

    语法:Promise.race( iterable)

    该方法同样是将多个Promise实例,包装成一个新的Promise实例。

    1 var p = Promise.race([p1, p2, p3]);

    Promise.race方法同样接受一个数组(或具有Iterator接口)作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilledrejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数。

    .resolve()

    语法:

    Promise.resolve(value);
    Promise.resolve(promise);
    Promise.resolve(thenable);

    它可以看做new Promise()的快捷方式。

    Promise.resolve('Success');
    
    /*******等同于*******/
    new Promise(function (resolve) {
        resolve('Success');
    });

    .reject()

    语法:Promise.reject(reason)
    

    这个方法和上述的Promise.resolve()类似,它也是new Promise()的快捷方式。

    Promise.reject(new Error('error'));
    
    /*******等同于*******/
    new Promise(function (resolve, reject) {
        reject(new Error('error'));
    });

    关于promise就先介绍到这边了,比较基础,有不足的地方欢迎指出,有更好的也欢迎补充~

    参考资料:

  • 相关阅读:
    SVN服务器搭建和配置使用详解
    Oracle命令大全
    mysql史上最全的学习资料
    jquery性能优化的38个建议
    vijosP1037搭建双塔
    vijosP1159 岳麓山上打水
    vijosP1038 添加括号
    BZOJP1003 [ZJOI2006]物流运输trans
    vijosP1006 晴天小猪历险记之Hill
    洛谷1043 数字游戏
  • 原文地址:https://www.cnblogs.com/ning123/p/10991471.html
Copyright © 2011-2022 走看看