Promise使用


Promise使用


正文

Promise前先说一下JavaScript的异步编程,试想一下我们Html及JavaScript页面加载都是同步模式,那么可想而知, 一个页面可以入眼需要很长的时间(即使是图片也只能一张一张挨个加载,页面结构都撑不起来), 如果是异步加载,那么css、图片等会立刻全部去请求并加载好,数据之后也会获取到,即使数据的获取需要一段时间,但是页面可以看了。

setTimeout() 函数就是一个异步函数,通过创建一个新线程处理定时任务,主线程继续向下执行。

XMLHttpRequest 常常用于请求来自远程服务器上的 XML 或 JSON 数据。 一个标准的 XMLHttpRequest 对象往往包含多个回调。 XMLHttpRequest是一个异步 AJAX。

jQuery 库中封装实现了异步 AJAX: $.get(), $.post() 等。

下面开始说Promise。

Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。

Promise 完全不是将异步转换为同步的方法,只不过是一种更良好的编程风格。

我们新建一个 Promise 对象:

new Promise(function (resolve, reject) {
    // 要做的事情...
}).then(function () {
    // resolve要做的事情...
}).catch(function (err) {
    console.log(err);
    // reject要做的事情...
}).finally(function () {
    console.log("End");
    // Promise运行结束要做的事情...
});

Promise 类有 .then() .catch().finally() 三个方法,这三个方法的参数都是一个函数。

.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列,顺序执行;

.catch() 则是设定 Promise 的异常处理序列;

.finally() 是在 Promise 执行的最后一定会执行的序列。

resolve 和 reject 都是函数,其中.then()调用 resolve 代表一切正常;reject 是出现异常时.catch()所调用的:

new Promise(function (resolve, reject) {
    var a = 0;
    var b = 1;
    if (b == 0) {
        reject("Diveide zero");
    } else {
        resolve(a / b);
    } 
}).then(function (value) {
    console.log("a / b = " + value);
}).catch(function (err) {
    console.log(err);
}).finally(function () {
    console.log("End");
});

输出:

a / b = 0
End

如果我想分三次输出字符串,第一次间隔 1 秒,第二次间隔 4 秒,第三次间隔 3 秒, 不使用Promise:

setTimeout(function () {
    console.log("First");
    setTimeout(function () {
        console.log("Second");
        setTimeout(function () {
            console.log("Third");
        }, 3000);
    }, 4000);
}, 1000);

用Promise实现:

new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log("First");
        resolve();
    }, 1000);
}).then(function () {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log("Second");
            resolve();
        }, 4000);
    });
}).then(function () {
    setTimeout(function () {
        console.log("Third");
    }, 3000);
});

使用Promise 函数的写法:

function print(delay, message) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log(message);
            resolve();
        }, delay);
    });
}

print(1000, "First").then(function () {
    return print(4000, "Second");
}).then(function () {
    print(3000, "Third");
});

这种返回值为一个 Promise 对象的函数称作 Promise 函数,它常常用于开发基于异步操作的库。

async function 中使用 await 指令实现:

function print(delay, message) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log(message);
            resolve();
        }, delay);
    });
}

async function asyncFunc() {
    await print(1000, "First");
    await print(4000, "Second");
    await print(3000, "Third");
}
asyncFunc();

异步函数 async function 中可以使用 await 指令,await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行。

异步函数实际上原理与 Promise 原生 API 的机制是一模一样的,只不过更便于程序员阅读。






参考资料

JavaScript Promise https://www.runoob.com/js/js-promise.html

JavaScript 异步编程 https://www.runoob.com/js/js-async.html

React教程: 第15天 Promise简介 https://blog.csdn.net/jim_loveq/article/details/106758396


返回