• Promise对象


    原文地址:https://wangdoc.com/javascript/

    概述

    Promise对象是JavaScript的异步操作解决方案,为异步操作提供统一接口。它起到代理作用,充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口。Promise可以让异步操作写起来,就像在写同步操作的流程,而不必一层层嵌套回调函数。
    首先,Promise是一个对象,也是一个构造函数。

    function f1(resolve, reject) {
        // 异步代码
    }
    
    var p1 = new Promise(f1);
    

    上面代码中,Promise构造函数接受一个回调函数f1作为参数,f1里面是异步操作的代码。然后,返回的p1就是一个Promise实例。
    Promise的设计思想是,所有异步任务都返回一个Promise实例。Promise实例有一个then方法,用来指定下一步的回调函数。

    var p1 = new Promise(f1);
    p1.then(f2);
    

    上面代码中,f1的异步操作完成,就会执行f2
    传统的写法可能需要把f2作为回调函数传入f1,比如写成f1(f2),异步操作完成后,在f1内部调用f2Promise使得f1f2变成了链式写法。不仅改善了可读性,而且对于多层嵌套的回调函数尤其方便。

    Promise对象的状态

    Promise对象通过自身的状态,来控制异步操作。Promise实例具有三种状态。

    • 异步操作未完成(pending)
    • 异步操作成功(fulfilled)
    • 异步操作失败(rejected)
      上面三种状态里面,fulfilledrejected合在一起称为resolved(已定型)。
      Promise的最终结果只有两种。
    • 异步操作成功,Promise实例传回一个值(value),状态变为fulfilled
    • 异步操作失败,Promise实例抛出一个错误(error),状态变为rejected

    Promise构造函数

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

    上面代码中,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供,不用自己实现。
    resolve函数作用是,将Promise实例状态从pending变为fulfilled,在异步调用成功时调用,并将异步调用结果作为参数传递出去。reject函数的作用是,将Promise实例的状态从pending变为rejected,在异步操作失败时调用,并将异步操作报错,作为参数传递出去。
    下面是一个例子:

    function timeout(ms) {
        return new Promise((resolve, reject) => {
            setTimeout(resolve, ms, "done"); // "done"作为参数传入resolve()
        });
    }
    
    timeout(100);
    

    上面代码中,timeout(100)返回一个Promise实例。100毫秒以后,该实例的状态会变为fulfilled

    Promise.prototype.then()

    Promise实例的then方法,用来添加回调函数。
    then方法接受两个回调函数,第一个是异步操作成功时(变为fulfilled状态的回调函数),第二个是异步操作失败(变为rejected)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。

    var p1 = new Promise(function (resolve, reject) {
        resolve("success");
    });
    p1.then(console.log, console.error);
    
    var p2 = new Promise(function (resolve, reject) {
        reject(new Error("failed"));
    });
    p2.then(console.log, console.error);
    

    上面代码中,p1p2都是Promise实例,它们then方法绑定两个回调函数:成功时回调函数console.log,失败时的回调函数console.error(可以省略)。
    then方法可以链式调用。

    p1.then(step1)
        .then(step2)
        .then(step2)
        .then(console.log, console.error);
    

    上面代码中,p1后面有四个then,意味着依次有四个回调函数。只要前一步的状态变为fulfilled,就会依次执行紧跟着在后面的回调函数。
    最后一个then方法,回调函数是console.logconsole.error,用法上有一个重要的区别。console.log只显示step3的返回值,而console.error可以显示p1step1step2step3之中任意一个发生的错误。

    then()用法辨析

    Promise的用法,简单说就是一句话:使用then方法添加回调函数。
    写法一

    f1().then(function () {
        return f2();
    }).then(f3);
    

    上面代码,f3的参数是f2函数运行的结果。
    写法二

    f1().then(function () {
        f2();
    }).then(f3);
    

    上面代码,f3的参数是undefined
    写法三

    f1().then(f2()).then(f3);
    

    上面代码,f3的参数是f2函数返回的函数运行的结果。
    写法四

    f1().then(f2).then(f3);
    

    写法四与写法一只有一个差别,那就是f2会接收到f1()返回的结果。

    实例:图片加载

    下面是使用Promise完成图片的加载。

    var preloadImage = function (path) {
        return new Promise(function (resolve, reject) {
            var image = new Image();
            image.onload = resolve;
            image.onerror = reject;
            image.src = path;
        });
    };
    
    preloadImage("url").then(function (e) {
        document.body.append(e.target);
    }).then(function () {
        console.log('加载成功'); 
    });
    
  • 相关阅读:
    Intel汇编语言程序设计学习-第三章 汇编语言基础-中
    Intel汇编语言程序设计学习-第三章 汇编语言基础-上
    对支付链接的加密处理 面向接口编程
    编制预算的四个好方法
    Twitter欲以10亿美元收购Flipboard 双方未置评
    分手决策——合伙人离婚时怎样保护你的公司
    领导力须突破命令控制式管理
    腾讯首席探索官建言创业者:尽可能留住早期员工
    人力资本管理的坏习惯
    我们在培训领导者这件事上行动迟缓
  • 原文地址:https://www.cnblogs.com/chris-jichen/p/10180618.html
Copyright © 2020-2023  润新知