zoukankan      html  css  js  c++  java
  • ES6之promise(resolve与reject)

    一、 Promise.resolve()

    有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。

    const jsPromise = Promise.resolve($.ajax('/whatever.json'));
    

    Promise.resolve等价于下面的写法。

    Promise.resolve('foo')
    // 等价于
    new Promise(resolve => resolve('foo'))
    

    Promise.resolve方法的参数分成四种情况。

    (1)参数是一个 Promise 实例

    如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

    //如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回。  
    function fn(resolve) {
      setTimeout(function () {
         return resolve(123);
      }, 3000);
    }
    let p0 = new Promise(fn);
    let p1 = Promise.resolve(p0);
    // 返回为true,返回的 Promise 即是 入参的 Promise 对象。
    console.log(p0 === p1);
    

    (2)参数是一个thenable对象

    thenable对象指的是具有then方法的对象,比如下面这个对象。

    let thenable = {
      then: function(resolve, reject) {
        resolve(42);
      }
    };
    

    Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
    ES6 Promises 里提到了 Thenable 这个概念,简单来说它就是一个非常类似 Promise 的东西。最简单的例子就是 jQuery.ajax,它的返回值就是 thenable 对象。
    但是要谨记,并不是只要实现了 then 方法就一定能作为 Promise 对象来使用。

    let thenable = {
    then: function(resolve, reject) {
    resolve(42);
    }
    };

    let p1 = Promise.resolve(thenable);
    p1.then(function(value) {
    console.log(value); // 42
    });

    上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。
    
    ###(3)参数不是具有then方法的对象,或根本就不是对象
    如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。
    ```JS
    const p = Promise.resolve('Hello');
    
    p.then(function (s){
      console.log(s)
    });
    // Hello
    

    上面代码生成一个新的 Promise 对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是resolved,所以回调函数会立即执行。
    Promise.resolve方法的参数,会同时传给回调函数。

    (4) 不带有任何参数

    Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

    所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve方法。

    const p = Promise.resolve();
    
    p.then(function () {
      // ...
    });
    

    上面代码的变量p就是一个 Promise 对象。

    参数不是具有then方法的对象,或根本就不是对象

    如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。

    const p = Promise.resolve('Hello');
    
    p.then(function (s){
      console.log(s)
    });
    // Hello


    需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时

    setTimeout(function () {
      console.log('three');
    }, 0);
    
    Promise.resolve().then(function () {
      console.log('two');
    });
    
    console.log('one');
    
    // one
    // two
    // three
    

    上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。

    Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
    console.log(1); // 1, 2, 3

    需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行执行,不是马上执行,也不是在下一轮“事件循环”的开始时执行
    原因:传递到 then() 中的函数被置入了一个微任务队列,而不是立即执行,这意味着它是在 JavaScript 事件队列的所有运行时结束了,事件队列被清空之后,才开始执行

    二、 Promise.reject()

    类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected。

    Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

    const p = Promise.reject('出错了');
    // 等同于
    const p = new Promise((resolve, reject) => reject('出错了'))
    
    p.then(null, function (s) {
      console.log(s)
    });
    // 出错了
    

    上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。
    注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致

    const thenable = {
      then(resolve, reject) {
        reject('出错了');
      }
    };
    
    Promise.reject(thenable)
    .catch(e => {
      console.log(e === thenable)
    })
    // true




    原文链接:https://www.jianshu.com/p/b511bfc58ae9

  • 相关阅读:
    又开始写代码了
    C# 调用office 2007 及 SaveAsPDFandXPS.exe 将Word、Excel、PPT转换为PDF文件
    64位机子上未能加载集
    在 vs 2003 转 2008 时WEB项目不能转换
    【第一弹】测试小学生,终于有博客了
    RobotFramwork + Appium+ Andriod 环境搭建
    写webpart
    backup
    获取MOSS当前登录用户信息
    rotate with different image(轮换显示图片)
  • 原文地址:https://www.cnblogs.com/fsg6/p/13167886.html
Copyright © 2011-2022 走看看