Jym好?,我是月弦笙音,今天给大家分享 为什么使用 reduce() 按顺序解析 promise 有效 ,嘎嘎的?,看下面
在不使用对象的情况下编写异步 js 很像闭着眼睛烤蛋糕。这是可以做到的,但它会很混乱,你最终可能会shao到自己。?
Promise
一、开题展示
我不会说这是必要的,但你明白了。真是太好了?。不过,有时它需要一点帮助来解决一些独特的挑战,比如当你试图按顺序解决一堆承诺时,一个接一个。 例如,当你通过 AJAX 进行某种批处理时,这样的技巧非常方便。你希望服务器处理一堆事情,但不是一次处理所有事情,因此随着时间的推移,你将处理间隔开来。
排除有助于简化此任务的包(如 Caolan McMahon 的异步库),最常建议的顺序解析 promise 的解决方案是获取一个事物的集合,并将它们简化为单个值,如下所示:Array.prototype.reduce()
javascript复制代码let result = [1,2,5].reduce((accumulator, item) => {
return accumulator + item;
}, 0); // <-- Our initial value.
console.log(result); // 8
但是,当用于我们的某种目的时,设置看起来更像是这样:reduce()
javascript复制代码let userIDs = [1,2,3];
userIDs.reduce( (previousPromise, nextID) => {
return previousPromise.then(() => {
return methodThatReturnsAPromise(nextID);
});
}, Promise.resolve());
或者,以更现代化的格式:
ini复制代码let userIDs = [1,2,3];
userIDs.reduce( async (previousPromise, nextID) => {
await previousPromise;
return methodThatReturnsAPromise(nextID);
}, Promise.resolve());
这很简洁!但在很长一段时间里,我只是知道这个解决方案,并将那段代码复制到我的项目中,因为它“有效”。 所以! 这篇文章是我要说清楚两件事:?
1. 为什么这种方法会奏效? ✔
2. 为什么我们不能用其他方法来做同样的事情?Array
✔
二、 为什么这种方法会奏效?
请记住,它的主要目的是将一堆东西“简化”为一个东西,它通过在循环运行时将结果存储来实现这一点。但这不一定是数字。循环可以返回它想要的任何内容(如 promise),并在每次迭代中通过回调回收该值。
值得注意的是,无论值是什么,循环本身都不会改变其行为,包括其执行速度。它只是在线程允许的范围内以最快的速度在集合中运行。reduce() accumulator
这很难理解,因为它可能违背了你认为在这个循环中发生的事情(至少,它对我来说是这样)。当我们使用它来按顺序解析 promise 时,reduce()
循环实际上根本没有减慢速度。 它是完全同步的,像往常一样尽可能快地做正常的事情。
看以下代码片段,并注意回调中返回的 promise 如何完全不阻碍循环的进度!?
javascript复制代码function methodThatReturnsAPromise(nextID) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Resolve! ${dayjs().format('hh:mm:ss')}`);
resolve();
}, 1000);
});
}
[1,2,3].reduce( (accumulatorPromise, nextID) => {
console.log(`Loop! ${dayjs().format('hh:mm:ss')}`);
return accumulatorPromise.then(() => {
return methodThatReturnsAPromise(nextID);
});
}, Promise.resolve());
在我们的控制台中:
arduino复制代码"Loop! 11:28:06"
"Loop! 11:28:06"
"Loop! 11:28:06"
"Resolve! 11:28:07"
"Resolve! 11:28:08"
"Resolve! 11:28:09"
promise 按照我们预期的顺序解析,但循环本身是快速、稳定和同步的。在查看了 的 MDN polyfill 之后,这是有道理的。循环一遍又一遍地触发,没有什么异步的,这就是引擎盖下发生的事情:reduce() while() callback()
ini复制代码while (k < len) {
if (k in o) {
value = callback(value, o[k], k, o);
}
k++;
}
真正的魔力就发生在这儿:
kotlin复制代码return previousPromise.then(() => {
return methodThatReturnsAPromise(nextID)
});
每次触发回调时,我们都会返回一个 promise,该 promise 解析为另一个 promise。虽然不会等待任何解决方案发生,但它确实提供的优势是能够在每次运行后将某些内容传递回同一个回调,这是独有的功能。因此,我们能够构建一个承诺链,这些承诺可以解析为更多的承诺,使一切都变得美好和有序:reduce()
look!?
javascript复制代码new Promise( (resolve, reject) => {
// Promise #1
resolve();
}).then( (result) => {
// Promise #2
return result;
}).then( (result) => {
// Promise #3
return result;
}); // ... and so on!
所以!这些也应该揭示为什么我们不能在每次迭代中只返回一个单一的新承诺。由于循环是同步运行的,因此每个 promise 都会立即触发,而不是等待之前创建的 promise
。
javascript复制代码[1,2,3].reduce( (previousPromise, nextID) => {
console.log(`Loop! ${dayjs().format('hh:mm:ss')}`);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Resolve! ${dayjs().format('hh:mm:ss')}`);
resolve(nextID);
}, 1000);
});
}, Promise.resolve());
在我们的控制台中:
arduino复制代码"Loop! 11:31:20"
"Loop! 11:31:20"
"Loop! 11:31:20"
"Resolve! 11:31:21"
"Resolve! 11:31:21"
"Resolve! 11:31:21"
是否可以等到所有处理完成后再做其他事情?是的。
同步性并不意味着你不能在每个项目都完全处理完毕后在进行下一步操作。看:reduce()
javascript复制代码function methodThatReturnsAPromise(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Processing ${id}`);
resolve(id);
}, 1000);
});
}
let result = [1,2,3].reduce( (accumulatorPromise, nextID) => {
return accumulatorPromise.then(() => {
return methodThatReturnsAPromise(nextID);
});
}, Promise.resolve());
result.then(e => {
console.log("Resolution is complete! Let's party.")
});
由于我们在回调中返回的只是一个链式 promise,因此当循环结束时,我们得到的就是:一个 promise。在那之后,我们可以随心所欲地处理它,即使在它已经走完了很久之后。reduce()
三、那为神马其他 Array 方法都不起作用??
请记住,在js的引擎下,我们不会等待回调完成,然后再进入下一个项目。它是完全同步的。所有这些其他方法也是如此:reduce()
Array.prototype.map()
Array.prototype.forEach()
Array.prototype.filter()
Array.prototype.some()
Array.prototype.every()
但是reduce()
很特别?
我们发现,之所以reduce
对我们有用,是因为我们能够将某些内容直接返回到我们相同的回调(即 promise),然后我们可以通过将它解析为另一个 promise 来构建它。
但是,对于所有这些其他方法,我们无法将参数传递给从回调返回的回调。相反,这些回调参数中的每一个都是预先确定的,因此我们无法利用它们来实现顺序承诺解析之类的事情。
ini复制代码[1,2,3].map((item, [index, array]) => [value]);
[1,2,3].filter((item, [index, array]) => [boolean]);
[1,2,3].some((item, [index, array]) => [boolean]);
[1,2,3].every((item, [index, array]) => [boolean]);
四、 结语
ok!我想这个为什么使用 reduce() 按顺序解析 promise 有效
我已经说的很明白了。
至少,我希望以上这些有助于阐明为什么唯有reduce有资格以这种方式处理承诺,并可能让你更好地了解常见方法在后台的运作方式。reduce() Array
感谢jym浏览本文,共同进步?,若有更好的建议,欢迎评论区讨论哈?。
如果jym觉得这篇干货很有用,可以加个关关?,点个赞赞?,后面我会继续分享更多干货!感谢支持!?
在数字化时代,电脑已成为我们日常生活和工作中不可或缺的工具。无论是进行网络冲浪、远程办公还是享受在线娱乐,稳定的网络连接都是基础中的基础。而IP地址,作为设备在网络中的唯一身份标识,其重要性不言而喻。特别是静态IP地址,它提供了一个固定的网络地址,使得设备无论何时何地都能被稳定地识别和访问。那么,如何查询电脑的静态IP地址呢?本文将详细讲解这一过程,确保即便是技术小白也能轻松上手。
一、理解IP地址的基本概念
在开始查询之前,我们首先需要明确几个基本概念。IP地址,全称Internet Protocol Address,是分配给网络上每一个设备的数字标签,用于在网络中定位和识别设备。根据分配方式的不同,IP地址分为静态(Static)和动态(Dynamic)两种。
(1)动态IP地址:由网络中的动态主机配置协议(DHCP)服务器自动分配,每次设备连接到网络时都可能发生变化。
(2)静态IP地址:手动设置或由网络管理员分配,一旦设定便不会改变,适用于需要稳定网络访问的场景,如服务器、网络摄像头等。
二、查询电脑静态IP地址的方法
方法1:通过Windows系统设置查询
对于大多数使用Windows操作系统的用户来说,查询静态IP地址的过程相对直观。下面以win10系统为例:
1. 打开网络和共享中心:
- 右键桌面右下角网络小图标,选择“打开网络和Internet设置”,在高级网络设置区域点击“网络和共享中心”按钮。
2. 进入属性设置:
- 在弹出的窗口中,点击左侧的“更改适配器设置”找到并点击当前正在使用的网络连接(如“本地连接”或具体的WiFi名称),在弹出的“网络连接状态”窗口中,点击“属性”按钮。
3. 查找Internet协议版本4(TCP/IPv4):
- 在属性列表中,找到并双击“Internet协议版本4(TCP/IPv4)”。
4. 查看IP地址:
- 在弹出的对话框中,你会看到“IP地址”、“子网掩码”、“默认网关”和“DNS服务器”等信息。如果这里显示的是一个固定的IP地址,那么它就是你的静态IP地址。
注意:如果在此处看到的是“自动获取IP地址”,则说明你的电脑当前使用的是动态IP地址,而非静态IP。
方法2:使用命令行查询
对于喜欢使用命令行界面的用户,或者需要在没有图形界面的服务器上操作时,可以使用以下步骤。
1. 打开命令提示符:
- 在Windows搜索框中输入“cmd”,然后按回车键,即可打开命令提示符窗口。
2. 输入ipconfig命令:
- 在命令提示符中输入“ipconfig”,然后按回车键。
3. 查看网络配置信息:
- 系统会显示当前所有网络适配器的配置信息,包括IP地址、子网掩码、默认网关等。找到与你当前网络连接相对应的适配器(如“以太网适配器 本地连接”),在其下方查看“IPv4 地址”字段。如果显示的是一个固定的IP地址,则表明你的电脑配置了静态IP。
方法3:通过路由器管理界面查询
如果你的电脑是通过路由器连接到互联网的,且路由器已为你分配了静态IP(这种情况多见于家庭或小型办公网络中的特定设备),你可以通过登录路由器管理界面来查询。
1. 获取路由器登录信息:
- 通常,路由器的登录地址(如192.168.1.1或192.168.0.1)和用户名/密码会印在路由器底部或随路由器附带的文档中。
2. 登录路由器管理界面:
- 打开浏览器,输入路由器的登录地址,然后输入用户名和密码进行登录。
3. 查找连接的设备:
- 在路由器管理界面中,找到“设备管理”或“已连接设备”等选项。
4. 查看IP地址信息:
- 在设备列表中,找到你的电脑,查看其对应的IP地址。如果这是一个固定的IP地址,且你之前没有在电脑上手动设置,那么很可能是路由器为你分配的静态IP。
三、注意事项与常见问题解决
- 确认网络环境:在查询前,请确认你的电脑已连接到网络,无论是有线还是无线。
- 区分静态与动态:如果通过上述方法发现你的电脑使用的是动态IP,而你确实需要静态IP,可以联系你的网络管理员或ISP(互联网服务提供商)申请配置。
- 权限问题:在某些情况下,你可能需要管理员权限才能查看或更改网络配置。
- IP地址冲突:在设置静态IP时,确保所选IP地址不与网络中其他设备的IP地址冲突,否则可能导致网络连接问题。
- 重启网络设备:有时,重启路由器或电脑可以解决网络配置更新后的问题。
四、总结
查询电脑的静态IP地址,虽然看似复杂,但只要掌握了正确的方法,就能轻松搞定。无论是通过Windows系统设置、命令行工具,还是路由器管理界面,都能帮助我们快速找到答案。了解并正确配置IP地址,不仅能提升我们的网络使用体验,还能在需要时进行更精细的网络管理。
评论记录:
回复评论: