1 创造一个阻塞线程的延迟函数
10毫秒延迟
await new Promise((resolve) => setTimeout(resolve, 10));
2 Promise.race的用法
Promise.race
是 JavaScript 中 Promise
对象的一个静态方法,它接收一个可迭代对象(通常是数组)作为参数,这个可迭代对象包含多个 Promise
实例。Promise.race
方法会返回一个新的 Promise
,这个新 Promise
会在传入的 Promise
数组中任意一个 Promise
完成(无论是成功还是失败)时,立即以相同的结果状态完成。
语法
Promise.race(iterable);
-
iterable
:一个可迭代对象,如数组,其中的每个元素都是一个Promise
实例。
返回值
返回一个新的 Promise
实例,它会根据传入的 Promise
数组中最先完成的 Promise
的结果来确定自身的状态和结果。如果最先完成的 Promise
成功(resolved
),那么返回的新 Promise
也会以相同的值成功;如果最先完成的 Promise
失败(rejected
),那么返回的新 Promise
也会以相同的错误原因失败。
示例代码
以下是一些使用 Promise.race
的示例,帮助你更好地理解它的用法。
示例 1:多个 Promise
竞争,先完成的决定结果
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve('Promise 1 完成');
}, 2000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve('Promise 2 完成');
}, 1000);
});
Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // 输出: Promise 2 完成
})
.catch((error) => {
console.error(error);
});
在这个例子中,promise2
比 promise1
先完成,所以 Promise.race
返回的 Promise
会以 promise2
的结果 'Promise 2 完成'
成功。
示例 2:包含失败的 Promise
const promise3 = new Promise((resolve) => {
setTimeout(() => {
resolve('Promise 3 完成');
}, 2000);
});
const promise4 = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error('Promise 4 失败'));
}, 1000);
});
Promise.race([promise3, promise4])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error.message); // 输出: Promise 4 失败
});
这里 promise4
先完成,但它是失败的,所以 Promise.race
返回的 Promise
会以 promise4
的错误原因 'Promise 4 失败'
失败。
实际应用场景
-
超时处理:在前面你提到的代码中,就使用
Promise.race
实现了超时处理。将一个异步操作和一个定时器Promise
放在一起竞争,如果定时器先完成,就认为异步操作超时了。 -
多个数据源获取数据:当有多个数据源可以获取相同的数据时,可以同时发起多个请求,使用
Promise.race
来获取最先返回的数据,提高响应速度。
给dealer添加超时返回机制
let reply;
let timer;
try {
// 使用Promise.race来进行超时控制和router的通信 有回复立即返回,超时则抛出超时错误
reply = await Promise.race([
dealer.receive(),
new Promise((resolve, reject) => {
timer = setTimeout(() => {
reject(new Error('Reply Timeout'));
}, timeout);
})
]);
} catch (error) {
if (error.message === 'Reply Timeout') {
clearTimeout(timer); // 清除定时器
dealer.close();
console.error(`${dealerID} 超时关闭`);
return 'Reply Timeout'; // 返回超时结果 停止循环
}
throw error; // 抛出非超时错误
}
3 Promise函数的三种返回值状态
-
pending(进行中)
这是 Promise 对象的初始状态。当你创建一个 Promise 实例时,它一开始就处于 pending 状态。在此状态下,Promise 的操作还在进行,结果尚未确定
const myPromise = new Promise((resolve, reject) => {
// 模拟一个耗时操作
setTimeout(() => {
// 这里在 3 秒后才会有结果,所以在这 3 秒内,Promise 处于 pending 状态
}, 3000);
});
console.log(myPromise);
不显示调用resolve
、reject
就会一直处于pending
状态
-
fulfilled(已成功)
当 Promise 内部的操作成功完成时,它会从 pending 状态转变为 fulfilled 状态。此时可以通过调用 resolve 函数来传递操作的结果
const myPromise = new Promise((resolve, reject) => {
// 模拟一个成功的操作
setTimeout(() => {
resolve('操作成功');
}, 2000);
});
myPromise.then((result) => {
console.log(result);
});
setTimeout
完成后,resolve
函数被调用,Promise 状态变为fulfilled
,then
方法中的回调函数会接收resolve
传递的值 '操作成功' 并执行。
-
rejected(已失败)
当 Promise 内部的操作出现错误或未能成功完成时,它会从 pending 状态转变为 rejected 状态。此时可以通过调用 reject 函数来传递错误信息
const myPromise = new Promise((resolve, reject) => {
// 模拟一个失败的操作
setTimeout(() => {
reject(new Error('操作失败'));
}, 2000);
});
myPromise.catch((error) => {
console.error(error.message);
});
setTimeout
完成后,reject
函数被调用,Promise
状态变为 rejected
,catch
方法中的回调函数会接收 reject 传递的错误对象并执行
还可以用then
函数同时处理fulfilled
和reject
myPromise.then(
(result) => {
console.log('成功结果:', result);
},
(error) => {
console.error('使用 then 捕获的错误:', error.message);
}
);
因为promise的返回结果是reject
,所以第一个回调函数不会执行
标准做法: 分别使用then
和catch
处理成功和失败
myPromise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error.message); // 输出: 操作失败
});
4 快速将对象包装为JSON和解JSON字符串
- 包装成字符串
const sendConfig = () => {
const config = {
userInput: userInput.value
};
const jsonConfig = JSON.stringify(config);
ipcRenderer.send('config', jsonConfig);
};
- 再解析为对象
ipcMain.on('config', (event, jsonConfig) => {
try {
const config = JSON.parse(jsonConfig);
console.log('接收到的配置:', config);
} catch (error) {
console.error('解析JSON时出错:', error);
}
});
5 快速按数字升/降序排列
升序
props.chatList.sort((a, b) => a.order - b.order) // 为负数,a在前,小的在前
降序
props.chatList.sort((a, b) => b.order - a.order) // 大的在前
更改会覆盖原数组
6 异步函数的默认返回promise.resolve机制
const myPromise = async () => {
return '你好'
}
写return
就自动返回promise.resolve
,不写隐式返回,只是promise.resolve = undefined
达到fulfilled
状态
7 打印对象内属性个数
console.log(Object.keys(groupContactList.value).length)
8 6个默认假值
JavaScript 里有 6 个值在转换为布尔值时会被当作假值,它们分别是:
- false
- 0
- ''(空字符串 双单引号)
- null
- undefined
- NaN
注意空对象{}
空数组[]
的布尔值是true
9 等待图片加载完成的回调函数
const preloadImage = (url, callback) => {
const img = new Image()
img.src = url
img.onload = () => {
callback(url) // 图片加载完成后执行回调
}
}
使用示例,等待图片加载完成设置为背景图片
preloadImage(selectedPostUrl, (loadedUrl) => {
requestAnimationFrame(() => {
setTimeout(() => {
console.log('backgroundImageUrl.value:', backgroundImageUrl.value)
backgroundImageUrl.value = loadedUrl // 延迟一段时间后再更新背景
}, 0)
backgroundImageUrl.value = loadedUrl // 记录当前加载图
})
})
10 多种快速查找数组中满足条件元素的方法
- Array.prototype.find() - 返回第一个满足条件的元素
const foundItem = chatList.value.find(chat => chat.user_id === selectedChat.value.user_id);
// foundItem 是找到的元素或undefined
- Array.prototype.some() - 检查是否存在满足条件的元素(返回布尔值)
const exists = chatList.value.some(chat => chat.user_id === selectedChat.value.user_id);
// exists 是 true/false
- Array.prototype.findIndex() - 返回第一个满足条件的元素索引
const index = chatList.value.findIndex(chat => chat.user_id === selectedChat.value.user_id);
// index 是索引号或-1
11 在组件中创建与销毁监听
处理函数
// 事件message:isSendSuccess的处理函数
const handleSendSuccess = (event, isSendSuccess) => {
if (isSendSuccess) {
inputTextObj = {...inputTextObj, ...{sendStatus: ' ', isStop: true}}
console.log('用户输入内容已成功发送至服务器')
emit('inputTextEvent', inputTextObj)
}
// 在组件创建时注册监听
onMounted(() => {
window.ipcRenderer.on(chatEvents.IS_SEND_SUCCESS, handleSendSuccess)
})
// 在组件销毁时移除监听
onBeforeUnmount(() => {
window.ipcRenderer.removeListener(chatEvents.IS_SEND_SUCCESS, handleSendSuccess)
})
12 把Date用对象形式打印出来
const dateStr = "2025-05-03 10:36:42";
const dateObj = new Date(dateStr);
console.dir(dateObj);
提取年月日 时分秒
const dateStr = "2025-05-03 10:36:42";
const dateObj = new Date(dateStr);
// 提取年月日
const year = dateObj.getFullYear(); // 2025
const month = dateObj.getMonth() + 1; // 5 (注意:月份从0开始,需+1)
const day = dateObj.getDate(); // 3
// 提取时分秒
const hours = dateObj.getHours(); // 10
const minutes = dateObj.getMinutes(); // 36
const seconds = dateObj.getSeconds(); // 42
console.log(`${year}-${month}-${day} ${hours}:${minutes}:${seconds}`);
// 输出: "2025-5-3 10:36:42"
按时时间排序:新——>旧
// 假设你的数组结构如下
const data = [
{id: 1, time: "2025-05-03 10:36:42"},
{id: 2, time: "2023-02-15 08:20:00"},
{id: 3, time: "2024-11-28 16:45:30"}
];
// 按时间降序排序(新在前,旧在后)
data.sort((a, b) => {
// 将时间字符串转换为Date对象的时间戳进行比较
return new Date(b.time).getTime() - new Date(a.time).getTime();
});
console.log(data);
13 async
只要一个函数用了async
,它的返回值一定是Promise
接收方可以获取传出的Promise
或者使用await
解包出内部resolved
值,也就是代码上写的
return XXX
或者resolved(XXX)
14 JS的push_front
于在数组开头添加一个或多个元素:
let arr = [2, 3];
arr.unshift(1); // 在数组前端插入
console.log(arr); // 输出: [1, 2, 3]
使用ES6展开运算符
let arr = [2, 3];
arr = [1, ...arr]; // 创建新数组
console.log(arr); // 输出: [1, 2, 3]
使用 concat() 方法
let arr = [2, 3];
arr = [1].concat(arr);
console.log(arr); // 输出: [1, 2, 3]