你有遇到过这样的情况吗?
function example(a) { // Default `a` to "foo" if (!a) { a = "foo"; } // or a = a || "foo"; }
某些初始化的时候需要一些冗长的逻辑代码
function example(opts) { // Ok, but could trigger setter. opts.foo = opts.foo ?? "bar"; // No setter, but 'feels wrong' to write. opts.baz ?? (opts.baz = "qux"); } example({ foo: "foo" });
function example(opts) { // 旧的方式 if (!a) { a = "foo"; } // or a = a || "foo"; // 新的方式 a ||= "foo" } example({ foo: "foo" });
function example(opts) { // 旧的方式 opts.foo = opts.foo ?? "bar"; // 新的方式 opts.foo ??= "bar"; // 旧的方式 opts.baz ?? (opts.baz = "qux"); // 新的方式 opts.baz ??= "qux"; } example({ foo: "foo" });
a = a + b; a += b; a = a - b; a -= b;
Promise.any
。 从字面意思来看,相信聪明的你应该能大致猜出这个 API 的作用。Promise.any
接受一个 Promise
的数组。当其中任何一个 Promise
完成(fullfill)时,就返回那个已经有完成值的 Promise
。如果所有的 Promise
都拒绝(reject),则返回一个拒绝的 Promise
,该 Promise
的返回值是一个 AggregateError
对象。
Promise.any(promises).then( (first) => { // 任意一个Promise完成了 }, (error) => { // 所有Promise都被拒绝了 } );
Promise.any([ fetch("https://v8.dev/").then(() => "home"), fetch("https://v8.dev/blog").then(() => "blog"), fetch("https://v8.dev/docs").then(() => "docs"), ]) .then((first) => { // Any of the promises was fulfilled. console.log(first); // → 'home' }) .catch((error) => { // All of the promises were rejected. console.log(error); });
例如一些播放平台,可以通过这个来测试当前延迟最低的线路是哪个,优先切换到对应的最快的线路。
来,亮出祖传降级代码
function reverse(promise) { return new Promise((resolve, reject) => Promise.resolve(promise).then(reject, resolve) ); } function promiseAny(iterable) { return reverse(Promise.all([...iterable].map(reverse))); } // https://github.com/m0ppers/promise-any/blob/master/index.js
实现很简单,通过一个反转函数,利用 Promisea.all
的特性,只要一个 Promise
被拒绝了,就进入到 reject
,因此反转 resolve
和 reject
就能模拟出 Promise.any
了。
let fee = 1000000000; let fee = 1_000_000_000;
这个模式不仅在十进制可以用,二进制,十六进制....甚至 BigInt,都可以使用。
// Binary Literals let nibbles = 0b1010_0001_1000_0101; // Hex Literal let message = 0xa0_b0_c0; // BigInt Literal const max = 2n ** (64n - 1n) - 1n; console.log(max === 9_223_372_036_854_775_807n);
以上特性均在最新版 chrome
支持,快打开控制台玩耍吧。
如果想要在实际项目中使用,请使用以下两个插件。