惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
J
Java Code Geeks
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
A
About on SuperTechFans
腾讯CDC
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
Y
Y Combinator Blog
Microsoft Security Blog
Microsoft Security Blog
F
Fortinet All Blogs
I
InfoQ
博客园 - 【当耐特】
美团技术团队
GbyAI
GbyAI
量子位
宝玉的分享
宝玉的分享
爱范儿
爱范儿
有赞技术团队
有赞技术团队
博客园 - Franky
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志

开飞机的老张

AGENTS.md Openspec 使用心得 从树莓派内网穿透到 Cloudflare Pages Openclaw和博客 郊眠寺 采石 译:我为什么使用Map(和WeakMap)处理DOM节点 介绍JavaScript中Symbol 原生JavaScript获取URL参数 字符串首字母大写 用forEach()遍历对象 JavaScript禁用按钮 JavaScript的FormData JavaScript的Blob 用FileReader读取本地文件 JavaScript的Thenable JavaScript中Promise的reject JavaScript的立即调用函数表达式(IIFE) JavaScript的Promise链 用interact.js实现拖拽、缩放、吸附 使用bluebird操作Promise JavaScript中Promise的catch函数 JavaScript比较数组
JavaScript创建Promise
kaifeiji.cc · 2023-03-02 · via 开飞机的老张

原文:JavaScript Create Promise

本文简述JavaScript创建Promise的几种方式。

总的来说,JavaScript有4种方式创建Promise:

Promise的构造器只接收一个参数——executor函数。当调用new Promise(executor)时,JavaScript会立即执行executor函数,传入2个参数:resolve()reject()

1
2
3
4
5
6
function executor(resolve, reject) {
typeof resolve;
typeof reject;
}

new Promise(executor);

executor()函数的作用,可以调用resolve()将Promise标记为fulfilled(成功),或调用reject()标记为rejected(失败)。

1
2
3
4
5
6
7
8
9
10
11
12
13
const success = new Promise(function executor(resolve) {
resolve('OK');
});

const fail = new Promise(function executor(resolve, reject) {
reject(new Error('Oops'));
});

const str = await success;
str;

const err = await fail.catch(err => err);
err.message;

静态函数

Promise.resolve()函数可以创建一个Promise,随后立即变为fulfilled。

1
2
3
4
const p = Promise.resolve(42);
p.then(v => {
v;
});

可以认为Promise.resolve(v)new Promise(resolve => resolve(v))的简写。

类似的,Promise.reject()函数可以创建一个立即标记为rejected的Promise。

1
2
3
4
const p = Promise.reject(new Error('Oops!'));
p.catch(err => {
err.message;
});

Promise.reject()时要小心:如果没有在其后加上.catch(),会发生“未处理的Promise异常”。

then()和catch()

在调用.then().catch()时,JavaScript会创建一个新的Promise。

1
2
3
4
5
6
const p = Promise.resolve('Hello');

const p2 = p.then(str => `${str} World`);

p2 instanceof Promise;
p2 === p;

async函数

在调用async函数时,JavaScript会返回一个新的Promise。无论async函数中返回的是什么,JavaScript都会返回一个Promise,一定要在async函数调用时加上await

1
2
3
4
5
async function test() {
return 42;
}

test() instanceof Promise;

不立即执行

JavaScript的Promise在创建时会立即执行executor函数,从这个角度来看,Promise是“热启动”的。

如果你需要一个“冷启动”的Promise,在创建时不执行,直到用await时才执行,那么你应该使用async函数。每次调用一个async函数都会返回一个新的Promise。

1
2
3
4
5
6
7
8
9
10
async function getAnswer() {
return 42;
}

const p1 = getAnswer();
p1 instanceof Promise;

const p2 = getAnswer();
p2 instanceof Promise;
p2 === p1;

另一种常见方式是延迟模式,可以创建一个Promise,但是在executor函数之外调用resolve()reject()函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Promise.deferred = function() {
let resolve = null;
let reject = null;
const p = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
return Object.assign(p, { resolve, reject });
};

const p = Promise.deferred();

p.then(v => {
v;
});

p.resolve(42);

然而延迟模式是一种反模式,因为executor函数之外发生的同步错误,不会把Promise标记为rejected!

1
2
3
4
5
6
7
8
9
10
11


const p1 = new Promise(() => { throw new Error('Oops!'); });
p1.catch(err => {
err.message;
});



const p2 = Promise.deferred();
throw new Error('Oops!');