我编写的代码看起来像:
function getStuffDone(param) { | function getStuffDone(param) {
var d = Q.defer(); /* or $q.defer */ | return new Promise(function(resolve, reject) {
// or = new $.Deferred() etc. | // using a promise constructor
myPromiseFn(param+1) | myPromiseFn(param+1)
.then(function(val) { /* or .done */ | .then(function(val) {
d.resolve(val); | resolve(val);
}).catch(function(err) { /* .fail */ | }).catch(function(err) {
d.reject(err); | reject(err);
}); | });
return d.promise; /* or promise() */ | });
} | }
Run Code Online (Sandbox Code Playgroud)
有人告诉我这个被称为" 延迟反模式 "或" Promise构造函数反模式 ",这个代码有什么不好,为什么这被称为 …
我收到以下警告:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace:
at EventEmitter.<anonymous> (events.js:139:15)
at EventEmitter.<anonymous> (node.js:385:29)
at Server.<anonymous> (server.js:20:17)
at Server.emit (events.js:70:17)
at HTTPParser.onIncoming (http.js:1514:12)
at HTTPParser.onHeadersComplete (http.js:102:31)
at Socket.ondata (http.js:1410:22)
at TCP.onread (net.js:354:27)
Run Code Online (Sandbox Code Playgroud)
我在server.js中编写了这样的代码:
http.createServer(
function (req, res) { ... }).listen(3013);
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?
我想澄清这一点,因为文件不太清楚;
Q1:是Promise.all(iterable)处理所有的承诺顺序或并行?或者,更具体地说,它是否相当于运行链式承诺
p1.then(p2).then(p3).then(p4).then(p5)....
Run Code Online (Sandbox Code Playgroud)
或者是一些其他类型的算法的所有p1,p2,p3,p4,p5,等是被称为在同一时间(并行)和结果尽快返回所有的决心(或一个拒绝)?
Q2:如果Promise.all并行运行,是否有一种方便的方式来运行可迭代的顺序?
注意:我不想使用Q或Bluebird,而是使用所有原生ES6规范.
我有几个项目需要查询第 3 方 API,并且该 API 的调用限制为每秒 5 次调用。我需要以某种方式将我对 API 的调用限制为每秒最多 5 次调用。
到目前为止,我只使用Promise.all()了一系列 promise,其中每个 promise 向 API 发送一个请求,并在 API 以 HTTP 状态代码响应时进行解析,200并在它以其他状态代码响应时拒绝。但是,当数组中有 5 个以上的项目时,我可能会面临Promise.all()拒绝的风险。
如何将Promise.all()呼叫限制为每秒 5 个呼叫?
假设我有一些像这样的asnyc可迭代对象:
// Promisified sleep function
const sleep = ms => new Promise((resolve, reject) => {
setTimeout(() => resolve(ms), ms);
});
const a = {
[Symbol.asyncIterator]: async function * () {
yield 'a';
await sleep(1000);
yield 'b';
await sleep(2000);
yield 'c';
},
};
const b = {
[Symbol.asyncIterator]: async function * () {
await sleep(6000);
yield 'i';
yield 'j';
await sleep(2000);
yield 'k';
},
};
const c = {
[Symbol.asyncIterator]: async function * () {
yield 'x';
await sleep(2000);
yield 'y'; …Run Code Online (Sandbox Code Playgroud) 我有一个函数可以对服务进行 REST 调用并返回一个承诺。让我们调用该函数 Execute()。该函数采用 ID 并将 ID 作为 GET 参数发送到 REST 端点,该端点将 ID 与一些附加信息一起保存在 mongoDB 数据库中。
在客户端中,我需要从 ID(0 到 100k)运行“执行”100k 次,并显示每个 ID 的状态(成功还是失败)。
我做了显而易见的事情,我创建了一个从 0 到 100k 的循环并运行执行传递“i。这导致我的 Chrome 最终冻结内存不足(资源不足)。它还导致后面所有其余调用的网络拥塞结尾。
所以我想把这 100k 切成可管理的数量,就像每个 50 个 Promise 调用一样。当这 50 个都完成时(无论失败还是成功),我想使用Promise.all([])。然后执行下一个 50,直到所有 100k 完成。这样我就可以同时控制网络拥塞和内存。但我似乎不知道如何摆脱这种情况。这是我的代码。
let promises = []
for (let i = 0; i < 100000, i++)
{
promises.push(execute(i))
if (i % 50 === 0)
{
Promise.all(promises)
.then (a => updateStatus (a, true))
.catch (a => updateStatus (a, false))
} …Run Code Online (Sandbox Code Playgroud) 有没有实现的方式/模式let res = Promise.all([...p], limit)?
res应该在所有p结算后解决limit=3Promise应该并行运行limit并行运行的解析器.特别是最后一点让我头疼.
我目前的解决方案是将promises-array拆分为limit大小的块并将它们链接起来.这里的缺点是第二组在第1组的所有Promise都已解决后才开始.
我正在寻找一个promise函数包装器,它可以在给定的promise运行时限制/限制,以便在给定的时间只运行一定数量的promise.
在下面的情况下delayPromise,永远不应该同时运行,它们应该以先来先服务的顺序一次运行一个.
import Promise from 'bluebird'
function _delayPromise (seconds, str) {
console.log(str)
return Promise.delay(seconds)
}
let delayPromise = limitConcurrency(_delayPromise, 1)
async function a() {
await delayPromise(100, "a:a")
await delayPromise(100, "a:b")
await delayPromise(100, "a:c")
}
async function b() {
await delayPromise(100, "b:a")
await delayPromise(100, "b:b")
await delayPromise(100, "b:c")
}
a().then(() => console.log('done'))
b().then(() => console.log('done'))
Run Code Online (Sandbox Code Playgroud)
关于如何获得像这样的队列设置的任何想法?
我有精彩的"去抖"功能Benjamin Gruenbaum.我需要修改它来根据它自己的执行而不是延迟来限制一个承诺.
export function promiseDebounce (fn, delay, count) {
let working = 0
let queue = []
function work () { …Run Code Online (Sandbox Code Playgroud) 在异步中,如果我需要对1000个项目应用异步函数,我可以这样做:
async.mapLimit(items, 10, (item, callback) => {
foo(item, callback);
});
Run Code Online (Sandbox Code Playgroud)
这样只能同时处理10个项目,从而限制了开销并允许控制.
有了ES6的承诺,我可以很轻松地做到:
Promise.all(items.map((item) => {
return bar(item);
}));
Run Code Online (Sandbox Code Playgroud)
这将同时处理所有1000个项目,这可能会导致很多问题.
我知道Bluebird有办法解决这个问题,但我正在寻找ES6解决方案.
我的问题基本上是一个组合
我知道Promise.allSettled,但我未能找到限制并发的好方法。
到目前为止我所拥有的:
想法1使用p-limit:
const pLimit = require('p-limit');
const limit = pLimit(10);
let promises = files.map(pair => {
var formData = {
'file1': fs.createReadStream(pair[0]),
'file2': fs.createReadStream(pair[1])
};
return limit(() => uploadForm(formData));
});
(async () => {
const result = await Promise.allSettled(promises).then(body => {
body.forEach(value => {
if(value.status == "rejected")
file.write(value.reason + '\n---\n');
});
});
})();
Run Code Online (Sandbox Code Playgroud)
我对这个解决方案的问题是,我必须首先创建所有承诺,并为此为每个承诺打开两个文件流,并且我将达到打开文件的限制。
想法 2使用p-queue:我尝试使用生成器函数在queue.on 'next'事件中创建和添加新的承诺,但我无法让它正常工作,这可能不是适合这项工作的工具。
使用 PromisePool 的想法 3:一开始这看起来很有希望。其中一些支持生成器函数来为池创建承诺,但我找不到一个明确声明其行为类似于Promise.allSettled.
javascript ×9
promise ×8
es6-promise ×5
node.js ×5
bluebird ×2
async-await ×1
concurrency ×1
ecmascript-6 ×1
eventemitter ×1
iterator ×1
memory-leaks ×1
q ×1
rest ×1
throttling ×1