zoukankan      html  css  js  c++  java
  • Promise对象

    Promise 承诺


    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
    它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
    就是一个对象,用来传递异步操作的数据(消息)
    pending(等待,处理中) =>Resolve(完成)
    =>Rejected
    只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
    一旦状态改变,就不会再变,任何时候都可以得到这个结果。
    const promise = new Promise(function(resolve, reject) {
    // ... some code
    if (/* 异步操作成功 */){
    resolve(value);
    } else {
    reject(error);
    }
    });
    Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
    它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

    resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为
    resolved),
    在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
    reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”
    (即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数
    传递出去。
    Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

    promise.then(function(value) {
    // success
    }, function(error) {
    // failure
    });
    then方法可以接受两个回调函数作为参数。
    第一个回调函数是Promise对象的状态变为resolved时调用,
    第二个回调函数是Promise对象的状态变为rejected时调用。
    其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
    下面是一个Promise对象的简单例子。
    function timeout(ms) {
    return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
    });
    }
    timeout(100).then((value) => {
    console.log(value);
    });
    上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。
    过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定
    的回调函数

    ----------------------------------------------------------
    Promise 新建后就会立即执行。

    let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    resolve();
    });

    promise.then(function() {
    console.log('resolved.');
    });

    console.log('Hi!');

    // Promise
    // Hi!
    // resolved
    上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。
    然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。

    -------------------------------------------------------------------------------------------
    var p1 = new Promise(function(resolve,reject){
    //resolve
    //reject
    })

    //Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    const p = Promise.all([p1, p2, p3]);
    //上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

    //p的状态由p1、p2、p3决定,分成两种情况。

    //(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

    //(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

    //下面是一个具体的例子。

    // 生成一个Promise对象的数组
    const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
    return getJSON('/post/' + id + ".json");
    });

    Promise.all(promises).then(function (posts) {
    // ...
    }).catch(function(reason){
    // ...
    });
    //上面代码中,promises是包含 6 个 Promise 实例的数组,只有这 6 个实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。

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

    const p = Promise.race([p1, p2, p3]);
    //上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    //Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。

    //下面是一个例子,如果指定时间内没有获得结果,就将 Promise 的状态变为reject,否则变为resolve。

    const p = Promise.race([
    fetch('/resource-that-may-take-a-while'),
    new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
    })
    ]);
    p.then(response => console.log(response));
    p.catch(error => console.log(error));
    //上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。

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

    const jsPromise = Promise.resolve($.ajax('/whatever.json'));
    //上面代码将 jQuery 生成的deferred对象,转为一个新的 Promise 对象。

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

    Promise.resolve('foo')
    // 等价于
    new Promise(resolve => resolve('foo'))
    //Promise.resolve方法的参数分成四种情况。
    //1 参数是一个 Promise 实例
    //如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
    //(2)参数是一个thenable对象

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

    let thenable = {
    then: function(resolve, reject) {
    resolve(42);
    }
    };
    //Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。

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

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

    const p = Promise.resolve('Hello');

    p.then(function (s){
    console.log(s)
    });
    // Hello

    //4)不带有任何参数

    //Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
    //所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve方法。


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

  • 相关阅读:
    05 | 深入浅出索引(下)
    04 | 深入浅出索引(上)
    03 | 事务隔离:为什么你改了我还看不见?
    02 | 日志系统:一条SQL更新语句是如何执行的?
    01 | 基础架构:一条SQL查询语句是如何执行的?
    orm的惰性机制
    简易的迁移
    rails 中 preload、includes、Eager load、Joins 的区别
    换种方式去分页
    Scala function programming
  • 原文地址:https://www.cnblogs.com/qdcnbj/p/8342669.html
Copyright © 2011-2022 走看看