我有一些代码在一个列表中进行迭代,该列表从数据库中查询并为该列表中的每个元素发出HTTP请求.该列表有时可能是一个相当大的数字(成千上万),我想确保我没有遇到数千个并发HTTP请求的Web服务器.
此代码的缩写版本目前看起来像这样......
function getCounts() {
return users.map(user => {
return new Promise(resolve => {
remoteServer.getCount(user) // makes an HTTP request
.then(() => {
/* snip */
resolve();
});
});
});
}
Promise.all(getCounts()).then(() => { /* snip */});
Run Code Online (Sandbox Code Playgroud)
此代码在Node 4.3.2上运行.重申Promise.all一下,可以进行管理,以便在任何给定时间只有一定数量的Promise正在进行中?
我有几个项目需要查询第 3 方 API,并且该 API 的调用限制为每秒 5 次调用。我需要以某种方式将我对 API 的调用限制为每秒最多 5 次调用。
到目前为止,我只使用Promise.all()了一系列 promise,其中每个 promise 向 API 发送一个请求,并在 API 以 HTTP 状态代码响应时进行解析,200并在它以其他状态代码响应时拒绝。但是,当数组中有 5 个以上的项目时,我可能会面临Promise.all()拒绝的风险。
如何将Promise.all()呼叫限制为每秒 5 个呼叫?
如何编写限制Q promise并发的方法?
例如,我有一个方法spawnProcess.它返回一个Q承诺.
我希望一次生成的进程不超过5个,但对调用代码透明.
我需要实现的是一个带签名的函数
function limitConcurrency(promiseFactory, limit)
Run Code Online (Sandbox Code Playgroud)
我可以这样打电话
spawnProcess = limitConcurrency(spawnProcess, 5);
// use spawnProcess as usual
Run Code Online (Sandbox Code Playgroud)
我已经开始研究我的版本,但我想知道是否有人有一个我可以检查的简洁实现.
我一直在尝试使用Typescript,但我现在对如何有效地使用async/await感到困惑.
我正在将一堆记录插入到数据库中,我需要获取每个插入返回的ID列表.以下简化示例通常起作用,但它并不像我想的那么优雅,而且完全是顺序的.
async function generatePersons() {
const names = generateNames(firstNames, lastNames);
let ids = []
for (let name of names) {
const id = await db("persons").insert({
first_name: name.firstName,
last_name: name.lastName,
}).returning('id');
ids.push(id[0])
}
return ids
}
Run Code Online (Sandbox Code Playgroud)
我试图用来map避免ids手动创建列表,但我可以让它工作.
我还想拥有的是有限的并行性.所以我的异步调用应该并行发生,直到某个限制,例如,我只想要有10个开放请求,但不是更多.
在Typescript或Javascript ES7中使用async/await实现这种有限的并行性是否有一种相当优雅的方式?或者我是否试图让这个功能做一些不适合的事情?
PS:我知道有数据库的批量插入方法,这个例子有点人为,因为我可以使用它来解决这个特定的问题.但它让我想知道我没有预定义批量方法的一般情况,例如网络请求
以下Typescript一次执行一个调用doSomething(action).(这意味着列表中的第二项在第一项完成之前不会进行调用).
async performActionsOneAtATime() {
for (let action of listOfActions) {
const actionResult = await doSomethingOnServer(action);
console.log(`Action Done: ${actionResult}`);
}
}
Run Code Online (Sandbox Code Playgroud)
这个会立即将所有请求发送到服务器(无需等待任何响应):
async performActionsInParallel() {
for (let action of listOfActions) {
const actionResultPromise = doSomething(action);
actionResultPromise.then((actionResult) => {
console.log(`Action Done: ${actionResult}`);
});
}
}
Run Code Online (Sandbox Code Playgroud)
但我真正需要的是一种限制它们的方法.也许一次打开10或20个电话.(一次一个太慢,但所有600都会使服务器超载.)
但我很难搞清楚这一点.
关于如何限制每次打开X的调用次数的任何建议?
(这个问题使用TypeScript,但我对ES6 JavaScript答案没问题.)
我想创建类似处理同步行为和异步行为的东西。例如,我希望能够像这样:
function timeout(myJson) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, myJson.wait, myJson);
});
}
async function funct() {
try {
let PromiseTolaunch = [{ "wait": 10, "nextIndex": 2, "id": 1 },
{ "wait": 500, "nextIndex": -1, "id": 2 },
{ "wait": 5, "nextIndex": -1, "id": 3 }];
let launchedPromise = [], finishedPromise;
launchedPromise.push(timeout(PromiseTolaunch[0]));
launchedPromise[0].id = PromiseTolaunch[0].id;
launchedPromise.push(timeout(PromiseTolaunch[1]));
launchedPromise[1].id = PromiseTolaunch[1].id;
while (launchedPromise.length !== 0) {
finishedPromise = await Promise.race(launchedPromise);
[*] console.log(finishedPromise); // Expected output: { "wait": 10, "nextIndex": 2 …Run Code Online (Sandbox Code Playgroud) 我有一个带有promise的函数,每次都必须使用不同的params执行n次.我想以一种方式链接承诺,即脚本当时总是处理3-4个承诺.
我用promise.all做了它,它同时执行3个,当所有的promises结算时,它继续下一个3.
如何使其工作,当3中的一个解决它立即与另一个开始,但总是在当时最大3工作?
for( var i = 0; i < tasks.length; i++){
if( i > 0 && i%3 == 0 ){
await Promise.all([
doTaskFunction(tasks[i]),
doTaskFunction(tasks[i-1]),
doTaskFunction(tasks[i-2]),
]);
}
}
Run Code Online (Sandbox Code Playgroud) 我想实现类似任务运行程序的东西,它将被推送新任务。这些任务中的每一个都可以是一些异步操作,例如等待用户或进行 API 调用或其他操作。任务运行程序确保一次只能执行允许数量的任务,而其他任务将继续等待,直到轮到它们。
class Runner {
constructor(concurrent) {
this.taskQueue = []; //this should have "concurrent" number of tasks running at any given time
}
push(task) {
/* pushes to the queue and then runs the whole queue */
}
}
Run Code Online (Sandbox Code Playgroud)
调用模式是
let runner = new Runner(3);
runner.push(task1);
runner.push(task2);
runner.push(task3);
runner.push(task4);
Run Code Online (Sandbox Code Playgroud)
其中任务是一个函数引用,它将在最后运行一个回调,我们可以知道它已完成。所以它应该像
let task = function(callback) {
/* does something which is waiting on IO or network or something else*/
callback();
}
Run Code Online (Sandbox Code Playgroud)
所以我正在推动跑步者的关闭,比如
runner.push(function(){return task(callback);});
Run Code Online (Sandbox Code Playgroud)
我想我可能还需要添加一个 waitList 队列。但任务本身并不是承诺,所以我不知道如何检查这些任务是否完成。
无论如何,我需要正确的方法。
使用node.js,我希望http.get以一次仅运行 10 个(或 n 个)的方式访问多个远程 url。
如果本地发生异常(m 次),我还想重试请求,但当状态代码返回错误(5XX、4XX 等)时,请求将被视为有效。
这对我来说真的很难理解。
问题:
似乎对于每个异步问题都建议使用 Promise,但我最终嵌套了太多 Promise,它很快就变得无法编码。
javascript ×9
node.js ×6
promise ×6
es6-promise ×3
async-await ×2
concurrency ×2
throttling ×2
typescript ×2
asynchronous ×1
ecmascript-6 ×1
q ×1