正文
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