资讯专栏INFORMATION COLUMN

Promise 详解

derek_334892 / 2132人阅读

摘要:是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理和更强大。规定,对象是一个构造函数,用来生成实例。在同步调用下,回调函数一般是最后执行的。

1、Promise 的含义
初识Promise,要从多方面去理解,可以直接百度Promise,只看别人博客的前面的含义介绍,先不深入看别人的博客,基本可以了解到:

promise原意:诺言; 许诺; 承诺;预示。

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。链接描述

Promises 是一种 JavaScript 中处理异步代码的方法,其实 Promises 已经存在多年,但是直到 ES2015 (ES6)才被标准化和引入,现在它们已经在 ES2017(ES8) 中被 async(异步) 函数所取代和扩展,可见发展之快。链接描述

一个 Promise 就是一个对象,它代表了一个异步操作的最终完成或者失败。链接描述

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

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

Async functions(异步函数) 使用 promises API 作为构建块,因此理解 Promises 是必须的,即使在较新的代码中,你可能会使用 async(异步) 函数而不是promises 。链接描述

2、同步、异步、回调函数相关概念

JavaScript的执行环境是单线程。所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会阻塞其他任务。这个任务可称为主线程。但实际上还有其他线程,如事件触发线程、ajax请求线程等。

同步模式,即上述所说的单线程模式,一次只能执行一个任务,函数调用后需等到函数执行结束,返回执行的结果,才能进行下一个任务。如果这个任务执行的时间较长,就会导致线程阻塞。

    /* 例2.1 */
    var x = true;
    while(x);
    console.log("don"t carry out");    //不会执行
    上面的例子即同步模式,其中的while是一个死循环,它会阻塞进程,因此第三句console不会执行。
    同步模式比较简单,也较容易编写。但问题也显而易见,如果请求的时间较长,而阻塞了后面代码的执行,
    体验是很不好的。因此对于一些耗时的操作,异步模式则是更好的选择。

异步模式,即与同步模式相反,可以一起执行多个任务,函数调用后不会立即返回执行的结果,如果任务A需要等待,可先执行任务B,等到任务A结果返回后再继续回调。最常见的异步模式就数定时器了,我们来看看以下的例子。

    /* 例2.2 */
    setTimeout(function() {
        console.log("taskA, asynchronous");
    }, 0);
    console.log("taskB, synchronize");
    //while(true);

    -------ouput-------
    taskB, synchronize
    taskA, asynchronous
    我们可以看到,定时器延时的时间明明为0,但taskA还是晚于taskB执行。
    这是为什么呢?由于定时器是异步的,异步任务会在当前脚本的所有同步 任务执行完才会执行。
    如果同步代码中含有死循环,即将上例的注释去掉,那么这个异步任务就不会执行,因为同步任务阻塞了进程。

回调函数,提起异步,就不得不谈谈回调函数了。上例中,setTimeout里的function便是回调函数。可以简单理解为:(执行完)回(来)调(用)的函数。

    **WikiPedia对于callback的定义。**
    In computer programming, a callback is a piece of executable code that is passed as 
    an argument to other code, which is expected to call back (execute) the argument 
    at some convenient time.
    可以看出,回调函数是一段可执行的代码段,它以「参数」的形式传递给其他代码,
    在其合适的时间执行这段(回调函数)的代码。
    **WikiPedia还定义**
    The invocation may be immediate as in a synchronous callback, 
    or it might happen at a later time as in an asynchronous callback.
    也就是说,回调函数不仅可以用于异步调用,一般同步的场景也可以用回调。
    在同步调用下,回调函数一般是最后执行的。而异步调用下,可能一段时间后执行或不执行(未达到执行的条件)。
3、Promise 的特点和基本用法
promise对象有两个特点:

对象的状态不受外界影响,pending(进行中)、fulfiled(已完成)、rejected(已失败)

一旦状态改变,就不会再变,任何时候都可以得到这个结果,状态改变只有两种可能,称为(resolved)

基本用法:
es6规定,Promise对象是一个构造函数,用来生成Promise实例。
扩展构造函数回顾:特殊方法,创建对象时初始化对象,为对象成员变量赋初始值,与new一起使用。
一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。
var promise = new promise(function(resove, reject){
  // ... some code
  if (/*异步成功*/){
    resove(value);
  } else{
    reject(error);。
  }
});
简单例子1 
例子用到了箭头函数,写法很容易理解,可参考另一篇文章
    let p= new Promise((resolve, reject)=>{
        let a1="成功传出去的对象";
        let a2="失败传出去的对象";
        var timer = setTimeout(function () {
                     console.log("after resolve");
                    resolve(a1);
                    reject(a2);
                    console.log("after error");
                }, 1000);
    });
    p.then(value=>{
        console.log(value);
    },error=>{
        console.log(".then的第二个参数");
        console.log(error)
    });
    p.catch(error=>{
        console.log(".catch");
        console.log(error);
    });
    

上面例子的输出效果,出现的第一行是Promise{},
然后再次输入p 按回车执行打印出来p是这样Promise{}
然后点开看 可以看到控制台提示promiseStatus :resolved 说明promise的状态已经成为了resolved

上面例子把resolve(a1)去掉,结果如下:

4、解读promise中唯一的参数、resolve参数、reject参数、then()、catch()方法的意义
参考上面例子1

let p = new Promise(参数1),创造一个实例时,接受一个函数作为参数1;

参数1,作为函数,也接受两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。注意:这两个函数的作用就是改变Promise对象的状态,一个是成功,一个是失败,一旦调用了其中一个,状态就不可改变和逆转;

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数,即使用p.then()来进一步的操作,注意:then()可以接受两个参数,这两个参数也是函数,第一个表示成功的操作,就是调用了resolve(a1)后会进入,第二个表示失败的操作,就是调用了reject(a1)后会进入,但第二个可以省略;

p.catch和.then()第二个参数的效果是一样,都会进入;

例子1的resolve(a1)和reject(a2)同时存在时,只有在前面的有用,可注释第一个看失败的效果;

例子中的resolve,reject只是个名字,其实可以随便改,不建议改;

例子中p.then(value=>{console.log(value)},这里面的value也只是个名字,其实可以随便改,不建议改;注意:value就是上面resolve(a1)中传出来的a1,a1可以是任何对象,a2也是相同的道理。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104255.html

相关文章

  • async await详解

    摘要:本身就是的语法糖。类似于后面代码会等内部代码全部完成后再执行打印结果操作符用于等待一个对象。它只能在异步函数中使用。参考附在版本位中是可以直接使用的。持续更新中来点颗吧 async await本身就是promise + generator的语法糖。 本文主要讲述以下内容 async awiat 实质 async await 主要特性 async await 实质 下面使用 pro...

    Shimmer 评论0 收藏0
  • async await详解

    摘要:本身就是的语法糖。类似于后面代码会等内部代码全部完成后再执行打印结果操作符用于等待一个对象。它只能在异步函数中使用。参考附在版本位中是可以直接使用的。持续更新中来点颗吧 async await本身就是promise + generator的语法糖。 本文主要讲述以下内容 async awiat 实质 async await 主要特性 async await 实质 下面使用 pro...

    KavenFan 评论0 收藏0
  • async await详解

    摘要:本身就是的语法糖。类似于后面代码会等内部代码全部完成后再执行打印结果操作符用于等待一个对象。它只能在异步函数中使用。参考附在版本位中是可以直接使用的。持续更新中来点颗吧 async await本身就是promise + generator的语法糖。 本文主要讲述以下内容 async awiat 实质 async await 主要特性 async await 实质 下面使用 pro...

    yedf 评论0 收藏0
  • Promise加载图片用法详解

    摘要:现在不会用都不好意思说自己是前端,为什么火起来,一句话解决了回调嵌套和执行顺序问题最重要的我感觉是解决顺序问题。 现在不会用Promise都不好意思说自己是前端,Promise为什么火起来,一句话解决了回调嵌套和执行顺序问题最重要的我感觉是解决顺序问题。 不过开始写之前我们先看看,promise怎么解决问题,怎么用。列举一个顺序加载图片demo: //需求 加载三张图片 img1,im...

    Brenner 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<