col*_*lby 5 javascript arrays settimeout node.js promise
我希望遍历一组用户(仅设置 id 属性),每两秒使用每个 id 调用一个端点,并将响应中关联的用户名存储到更新的数组中。
例如更新 [{ id: 1 }] 到 [{ id: 1, name: "Leanne Graham" }]
这是我的代码:
const axios = require('axios');
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
function addNameToUser(user) {
return new Promise((resolve) => {
axios.get(`https://jsonplaceholder.typicode.com/users/${user.id}`)
.then(response => {
user.name = response.data.name
resolve(user);
});
})
}
const requests = users.map((user, index) => {
setTimeout(() => {
return addNameToUser(user);
}, index * 2000);
});
Promise.all(requests).then((updatedArr) => {
console.log(updatedArr);
});
Run Code Online (Sandbox Code Playgroud)
没有setTimeout,一切都很好,但重要的是我每两秒钟只发送一个请求。因此,对于三个用户,我希望Promise.all在 6 秒左右后从我的日志中查看结果。
值得注意的是:这不是我正在处理的实际问题,而是我能想出的最简单的例子来帮助突出问题。
您需要从地图的回调中返回一个 Promise。由于此 Promise 将由 解析setTimeout(),因此我们将使用Promise 构造函数。
已解决的超时承诺应返回 Axios 承诺,该承诺将在解决后返回结果。
注意:由于 Axios 返回一个 Promise,我们不需要用另一个 Promise 构造函数来包装它。请参阅什么是显式承诺构造反模式以及如何避免它?问题和答案。
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
const addNameToUser = (user) =>
axios.get(`https://jsonplaceholder.typicode.com/users/${user.id}`)
.then(({ data }) => ({
...user,
name: data.name
}));
const requests = users.map((user, index) =>
new Promise(resolve =>
setTimeout(() => resolve(addNameToUser(user)), index * 2000)
));
Promise.all(requests).then((updatedArr) => {
console.log(updatedArr);
});Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>Run Code Online (Sandbox Code Playgroud)
据我了解,您问题的核心是如何将处理间隔 2 秒,对吗?
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
/* throttledProcess is a function that does your processing spaced by the given interval millisecond */
const throttledProcess = (items, interval) => {
if (items.length == 0) { // stop when there's no more items to process
console.log('ALL DONE')
return
}
console.log('PROCESSING', items[0], Date()) // this is where your http call/update/etc takes place
setTimeout(() => throttledProcess(items.slice(1), interval), // wrap in an arrow function to defer evaluation
interval)
}
throttledProcess(users, 2000) // run process. shows output every 2 secondsRun Code Online (Sandbox Code Playgroud)
运行此代码,每 2 秒,它将注销正在处理的用户。
希望这可以帮助。干杯,
| 归档时间: |
|
| 查看次数: |
1852 次 |
| 最近记录: |