JS promise(承诺)
最后修改于 2023 年 10 月 18 日
在本文中,我们将展示如何在 JavaScript 中使用 promises。
Promise 代表一个潜在的值或错误,该值或错误将在未来某个时间点可用。
Promise 可以具有以下状态之一:
- pending - 初始状态,既未 fulfilled 也未 rejected(未完成)
- fulfilled - 操作已成功完成
- rejected - 操作失败
我们使用回调函数或 async/await 关键字来处理 promises。
在某些编程语言中,promises 被称为 futures(未来)。
JS Promise.resolve
Promise.resolve 方法返回一个 Promise 对象,该对象以给定的值解析。
let promise = new Promise(resolve => {
setTimeout(() => resolve(2), 2000);
});
promise.then(val => console.log(val));
console.log('finished');
我们创建一个 promise,该 promise 在两秒后以一个整数值解析。 then 函数附加回调函数,用于处理 promise 的 resolve 和/或 reject(完成和/或拒绝)。
$ node main.js finished 2
在下一个示例中,我们使用 async/await 关键字。
async function doWork() {
let res = await promise;
console.log(res);
}
let promise = new Promise(resolve => {
setTimeout(() => resolve(2), 2000);
});
doWork();
console.log('finished');
await 关键字用于等待一个 Promise。它只能在 async 函数内部使用。
JS promise 错误
Promise.reject 方法返回一个 Promise 对象,该对象以给定的原因被 reject(拒绝)。
let promise = new Promise((resolve, reject) => {
let b = Math.random() < 0.3;
if (b) {
resolve(10);
} else {
reject("promise error");
}
});
promise.then(val => console.log(val)).catch(err => {
console.log(`${err}`)
});
console.log('finished');
在示例中,我们使用 Math.random 模拟一个错误。我们使用 catch 方法捕获该错误。
$ node main.js finished promise error $ node main.js finished promise error $ node main.js finished 10
JS 链式 promise
可以使用链式操作执行多个异步操作。
let p = new Promise((resolve) => {
resolve(1);
});
let r = p.then(val => val + 2).then(val => val + 3)
.then(val => val + 4).then(val => console.log(val));
console.log('finished');
该示例通过链式 promise 添加四个整数。
$ node chain.js finished 10
JS Promise.all
Promise.all 方法将一个 promises 的可迭代对象作为参数,并返回一个单一的 promise,该 promise 解析为给定 promises 结果的数组。
当所有 promises 都已解析时,此返回的 promise 会解析。如果任何输入 promises 被 rejected(拒绝)并带有错误,它会立即被拒绝。
const p1 = new Promise((resolve) => setTimeout(resolve, 100, 100));
const p2 = new Promise((resolve) => setTimeout(resolve, 300, 200));
const p3 = new Promise((resolve) => setTimeout(resolve, 500, 300));
const promises = [p1, p2, p3];
Promise.all(promises).then((data) =>
console.log(data.reduce((total, next) => total + next)));
console.log('finished');
在示例中,我们等待所有 promises 完成,最后,我们计算返回值的总和。
$ node all.js finished 600
JS 使用 axios 进行多次请求
在下一个示例中,我们使用 axois 库执行多个 get 请求。 Axios 是一个基于 promise 的 HTTP 客户端,适用于 Node 和浏览器。
$ npm i axios
我们安装 Axios 库。
const axios = require('axios');
async function makeRequests(urls) {
const fetchUrl = (url) => axios.get(url);
const promises = urls.map(fetchUrl);
let responses = await Promise.all(promises);
responses.forEach(resp => {
let msg = `${resp.config.url} -> ${resp.headers.server}: ${resp.status}`;
console.log(msg);
});
}
let urls = [
'http://webcode.me',
'https://example.com',
'http://httpbin.org',
'https://clojure.org',
'https://fsharp.org',
'https://symfony.com.cn',
'https://perl.net.cn',
'https://php.ac.cn',
'https://pythonlang.cn',
'https://vscode.js.cn',
'https://github.com'
];
makeRequests(urls);
我们使用 Promise.all 等待所有请求完成。完成后,我们遍历响应数组、服务器名称和响应状态。
$ node main.js http://webcode.me -> nginx/1.6.2: 200 https://example.com -> ECS (dcb/7ECA): 200 http://httpbin.org -> gunicorn/19.9.0: 200 https://clojure.org -> AmazonS3: 200 https://fsharp.org -> GitHub.com: 200 https://symfony.com.cn -> cloudflare: 200 https://perl.net.cn -> Combust/Plack (Perl): 200 https://php.ac.cn -> myracloud: 200 https://pythonlang.cn -> nginx: 200 https://vscode.js.cn -> Microsoft-IIS/10.0: 200 https://github.com -> GitHub.com: 200
JS 使用 Puppeteer 创建 PDF
在下面的示例中,我们使用 Puppeteer 库从网页生成 PDF 文件。
$ npm i puppeteer
我们安装 Puppeteer。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('http://webcode.me');
await page.pdf({ path: 'webcode.pdf', format: 'a5' });
await browser.close();
})();
整个任务由几个异步操作组成,这些操作使用 async/await 关键字处理。
来源
在本文中,我们使用 JavaScript 中的 promises。