zoukankan      html  css  js  c++  java
  • js之Promise

    一、什么是Promise

    Promise 是抽象的异步处理对象,以及对其进行各种操作的组件。

    Promise最初被提出是在 E语言中, 它是基于并列/并行处理设计的一种编程语言。Javascript 在 ES6 之后也开始支持 Promise 特性了,用来解决异步操 的问题。这里顺便解释一下什么是 ES6, ECMAScript 是 Javascript 语言的国际标准,Javascript 是 ECMAScript 的有一个实现, 而ES6(全称 ECMAScript 6)是这个标准的一个版本。

    谈到异步操作,你可能会说,Javascript 不是可以用回调 函数处理异步操作吗? 原因就是 Promise 是一种更强大的异步处理方式,而且她有统一的 API 和规范。

    二、promise的用法

    • Promise是一个构造函数,所以可以 new 出一个Promise的实例
    • 在Promise上有两个函数 resolve(成功之后的回调函数)和 reject(失败后的回调函数)
    • 在Promise构造函数的prototype属性上,有一个 .then() 方法。所以只要是Promise构造函数创建的实例,都可以访问到 .then()方法
    • Promise表示一个一步操作,每当我们new一个Promise的实例,这个实例就代表具体的异步操作。
    • Promise创建的实例,是一个异步操作,这个异步操作结果,只有两种结果

           状态1:异步执行成功,需要在内部调用成功的回调函数resolve把结果返回给调用者(Fulfilled状态)

           状态2:异步执行失败,需要在内部调用失败的回调函数reject把结果返回调用者(Rejected状态)

         (注:其实Promise创建示例时还有一个Pending状态,但不存在于操作结果内,表示待解决,既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态.)

    • 由于Promise的实例是一个异步操作,所以内部拿到操作结果后,无法使用return把操作结果返回给调用者,这个时候只能使用回调函数的形式,把成功或失败的结果,返回给调用者

          我们可以在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数

    在 ES6 中,可以使用三种办法创建 Promise 实例(对象)

    (1). 构造方法

    let promies = new Promise((resolve, reject) => {
     resolve(); //异步处理 
    });

    Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

    (2). 通过 Promise 实例的方法,Promise#then 方法返回的也是一个 Promise 对象

    promise.then(onFulfilled, onRejected);

    (3). 通过 Promise 的静态方法,Promise.resolve(),Promise.reject()

    var p = Promise.resolve();
    p.then(function(value) {
     console.log(value); 
    });

    示例:创建一个完整的方法(下面的函数aa,bb均可创建)

    function aa() {
        var p = new Promise((resolve, reject) => {
            alert('处理过程');
            resolve("结果")
        })
        return p;
    }
    
    function bb() {
        var p = new Promise(function (resolve, reject) {
            alert('处理过程,得到结果');
            resolve("结果")
        })
        return p;
    }

    我对他的简单理解就是:aa函数委托promise做事情,alert()的部分代替了事件处理的过程,resolve()中的内容代表事件处理的结果,然后return p相当于promise处理完aa交代的事件后给它返回一个交代。上述示例除了resolve外,还有可以有reject(),reject()代表事件处理没有办成的一个结果。

    可以直接使用reject()方法或resolve()方法,表示Promise被拒绝的原因或继续执行。

    Promise.reject(reason);
    //

    var promise1 = Promise.resolve(123);

    promise1.then(function(value) {
    console.log(value);
    // expected output: 123
    });

    下面给一个完整的例子

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <h2>需求:promise执行解决晚餐过程</h2>   <br>
        1.煲汤  <br>
        2.洗菜  <br>
        3.做饭  <br>
        4.吃饭  <br>
    5.洗碗 <br> </body> <script> let condition =true; function step1(resolve,reject){ console.log("放料,加水,插电"); if(condition==true){ resolve("煲好汤了") }else{ reject("没电了") } } function step2(resolve,reject){ console.log("洗菜"); if(condition==true){ resolve("洗好了"); }else{ reject("没水了"); } } function step3(resolve,reject){ console.log("开始做饭"); if(condition==true){ resolve("做好了"); }else{ reject("没火了"); } } function step4(resolve,reject){ console.log("准备吃饭"); if(condition==true){ resolve("真好吃"); }else{ reject("真难吃"); } } function step5(resolve,reject){ console.log("准备洗碗"); if(condition==false){ resolve("不想洗"); }else{ reject("洗"); } } new Promise(step1).then((val1)=>{ console.log(val1); return new Promise(step2) }).then((val2)=>{ console.log(val2); return new Promise(step3) }).then((val3)=>{ console.log(val3) return new Promise(step4) }).then((val4)=>{ console.log(val4) return new Promise(step5) }).then((val5)=>{ console.log(val5) }) </script> </html>

    三、Promise.all()方法

    Promise.all(iterable) 方法返回一个 Promise实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中  promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。即多个promise都执行,全部执行完之后再执行下一步。

    var promise1 = Promise.resolve(3);
    var promise2 = 42;
    var promise3 = new Promise(function(resolve, reject) {
      setTimeout(resolve, 100, 'foo');
    });
    
    Promise.all([promise1, promise2, promise3]).then(function(values) {
      console.log(values);
    });
    // expected output: Array [3, 42, "foo"]

    四、Promise.prototype.then()方法

    Promise.prototype.then()即当promise执行完后,再执行某一函数

    var promise1 = new Promise(function(resolve, reject) {
      resolve('Success!');
    });
    
    promise1.then(function(value) {
      console.log(value);
      // expected output: "Success!"
    });

    五、Promise.prototype.catch()方法

    catch() 方法返回一个Promise,并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected) 相同,即当执行失败时返回一个函数。

    p.catch(onRejected);
    
    p.catch(function(reason) {
       // 拒绝
    });

    六、Promise.prototype.finally()方法

    finally() 方法返回一个Promise,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()catch()后,都会执行finally指定的回调函数。这为指定执行完promise后,无论结果是fulfilled还是rejected都需要执行的代码提供了一种方式,避免同样的语句需要在then()catch()中各写一次的情况。

    p.finally(onFinally);
    
    p.finally(function() {
       // 返回状态为(resolved 或 rejected)
    });参数

    七、Promise.prototype.race()方法

    Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

    var promise1 = new Promise(function(resolve, reject) {
        setTimeout(resolve, 500, 'one');
    });
    
    var promise2 = new Promise(function(resolve, reject) {
        setTimeout(resolve, 100, 'two');
    });
    
    Promise.race([promise1, promise2]).then(function(value) {
      console.log(value);
      // Both resolve, but promise2 is faster
    });
    // expected output: "two"

    八、dojo中的Promise方法

     1、dojo/promise/Promise

    dojo / promise / Promise定义了Dojo Promises API,是一个抽象类。 例如,dojo / Deferred实现了类。该类旨在封装异步线程之间的通信。

    define(["dojo/promise/Promise", "dojo/_base/declare"], function(Promise, declare){
      return declare([Promise], {
        then: function(){
          // Implementation of .then()
        },
        cancel: function(){
          // Implementation of .cancel()
        },
        isResolved: function(){
          // Implementation of .isResolved()
        },
        isRejected: function(){
          // Implementation of .isRejected()
        },
        isFulfilled: function(){
          // Implementation of .isFulfilled()
        },
        isCanceled: function(){
          // Implementation of .isCanceled()
        }
      });
    });

     2、dojo/promise/all

    dojo / promise / all是一个函数,它接受多个promise并返回一个新的promise,当所有promises都已完成时,它将被履行。

    require(["dojo/promise/all"], function(all){
    
      all([promise1, promise2]).then(function(results){
        // results will be an Array
      });
    
      // -- or --
    
      all({
        promise1: promise1,
        promise2: promise2
      }).then(function(results){
        // results will be an Object using the keys "promise1" and "promise2"
      });
    
    });

     3、dojo/promise/first

    dojo / promise / first是一个函数,它接受多个promise并返回一个新的promise,当第一个promise完成时,它会被满足。

    require(["dojo/promise/first"], function(first){
    
      first([promise1, promise2]).then(function(result){
        // result will be either promise1 or promise2 results, whichever is fulfilled first
      });
    
      // -- or --
    
      first({
        promise1: promise1,
        promise2: promise2
      }).then(function(result){
        // result will be either promise1 or promise2 results, whichever is fulfilled first
      });
    
    });

     

  • 相关阅读:
    工作中问题的总结1
    linux问题故障
    时间转换
    Tips
    总结
    方向
    同步&异步-阻塞&非阻塞
    IO 之 mark()、reset()
    GC日志分析
    JDK 部分工具使用方法
  • 原文地址:https://www.cnblogs.com/tangguobo/p/11024736.html
Copyright © 2011-2022 走看看