首页 > 编程笔记 > JavaScript笔记 阅读:25

JavaScript Promise对象详解(附带实例)

ES6 提供了 Promise 对象,它是异步编程的一种解决方案,比传统的“回调函数和事件”解决方案更合理、更强大。

ES6 规定,Promise 对象是一个构造函数,用来生成 Promise 实例。语法如下:
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 新建后就会立即执行。

Promise 实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数:
promise.then(function(value) {
    // success
}, function(error) {
    // failure
});
then 方法可以接收两个回调函数作为参数:
这两个函数都是可选的,不一定要提供。它们都接收 Promise 对象传出的值作为参数。then 方法指定的回调函数将在当前脚本所有同步任务执行完后才会执行。

【实例 1】Promise 基本用法。
<h1 id="demo"></h1>
<script>
     const myPromise = new Promise(function(myResolve, myReject) {
         setTimeout(function() { myResolve("hello"); }, 3000);
     });
     myPromise.then(function(value) {
         document.getElementById("demo").innerHTML = value;
     });
</script>
程序中第 3 行代码创建了一个 Promise 实例;等待 3 秒之后,Promise 实例的状态变为 resolved,就会触发第 6 行 then 方法绑定的回调函数,修改元素内容;第 7 行 value 的值是第 4 行 myResolve 方法传递的数据“hello”。

【实例 2】Promise 对象实现等待文件异步加载。
<script>
let myPromise = new Promise(function(myResolve, myReject) {
    let req = new XMLHttpRequest();
    req.open('GET', "1.html");
    req.onload = function () {
        if (req.status == 200) {
            myResolve(req.response); // 成功
        } else {
            myReject("File not Found"); // 失败
        }
    };
    req.send();
});
myPromise.then(
    function(value) { console.log(value); },
    function(error) { console.log(error); }
);
</script>
程序中,第 2 行代码创建了一个 Promise 实例,等待文件异步加载。文件加载成功或失败都会触发第 14 行 then 方法绑定的回调函数,输出相应的数据。

由于要访问本地文件,程序需要在服务器环境下运行,可以使用 VS Code 插件 Live Server,选择“Open With Live Server”打开页面。

【实例 3】Promise 对象实现 Ajax 异步操作。
<script>
const promise = new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "服务器地址", true);
    xhr.onreadystatechange = function () {
        if (this.readyState !== 4) {
            return;
        }
        if (xhr.status == 200) {
            resolve(xhr.responseText); // 成功
        } else {
            reject(xhr.status);//失败
        }
    }
    xhr.send();
});
promise.then(function(res) {
    console.log(res);
}, function(error) {
    console.error('出错了', error);
});
</script>
程序中,第 2 行代码创建了一个 Promise 实例,等待 Ajax 异步请求。请求成功或失败都会触发第 18 行 then 方法绑定的回调函数,输出相应的数据。

提示,Axios 是一个基于 promise 的网络请求库,作用于 node.js 和浏览器中。Axios 本质上也是对原生 XMLHttpRequest 的封装。它是 Promise 的实现版本,符合最新的 ES 规范。

相关文章