我使用async.eachLimit
功能一次控制最大操作次数。
const { eachLimit } = require("async");
function myFunction() {
return new Promise(async (resolve, reject) => {
eachLimit((await getAsyncArray), 500, (item, callback) => {
// do other things that use native promises.
}, (error) => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
正如您所看到的,我无法将myFunction
函数声明为异步,因为我无法访问eachLimit
函数的第二个回调中的值。< / p>
答案 0 :(得分:28)
你在promise构造函数执行函数中有效地使用了promise,所以这就是Promise constructor anti-pattern。
您的代码是主要风险的一个很好的例子:不安全地传播所有错误。阅读there。
的原因此外,使用async
/ await
可以使相同的陷阱更令人惊讶。比较:
let p = new Promise(resolve => {
""(); // TypeError
resolve();
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e)); // Catches it.
有一个天真的(错误的)async
等价物:
let p = new Promise(async resolve => {
""(); // TypeError
resolve();
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e)); // Doesn't catch it!
在浏览器的Web控制台中查找最后一个。
第一个可行,因为Promise构造函数执行函数中的任何立即异常都会方便地拒绝新构造的promise(但在你自己的任何.then
内)。
第二个不起作用,因为async
函数中的任何立即异常都会拒绝async
函数本身返回的隐式承诺。
由于promise构造函数执行函数的返回值未使用,这是个坏消息!
您无法将myFunction
定义为async
:
async function myFunction() {
let array = await getAsyncArray();
return new Promise((resolve, reject) => {
eachLimit(array, 500, (item, callback) => {
// do other things that use native promises.
}, error => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
虽然为什么在await
时使用过时的并发控制库?
答案 1 :(得分:20)
我同意上面给出的答案,但有时,在您的诺言中保持异步有时会更明智,尤其是如果您希望将多个返回诺言的操作链接在一起并避免陷入then().then()
地狱的时候。我会考虑在这种情况下使用类似的方法:
const operation1 = Promise.resolve(5)
const operation2 = Promise.resolve(15)
const publishResult = () => Promise.reject(`Can't publish`)
let p = new Promise((resolve, reject) => {
(async () => {
try {
const op1 = await operation1;
const op2 = await operation2;
if (op2 == null) {
throw new Error('Validation error');
}
const res = op1 + op2;
const result = await publishResult(res);
resolve(result)
} catch (err) {
reject(err)
}
})()
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e));
Promise
构造函数的函数不是异步的,因此linters不会显示错误。await
按顺序调用所有异步函数。但是,缺点是您必须记住将try/catch
放在并将其附加到reject
上。
答案 2 :(得分:4)
static getPosts(){
return new Promise( (resolve, reject) =>{
try {
const res = axios.get(url);
const data = res.data;
resolve(
data.map(post => ({
...post,
createdAt: new Date(post.createdAt)
}))
)
} catch (err) {
reject(err);
}
})
}
删除等待和异步将解决此问题。因为您已经应用了Promise对象,就足够了。
答案 3 :(得分:0)
相信反模式就是反模式
异步承诺回调中的抛出很容易被捕获。
(async () => {
try {
await new Promise (async (FULFILL, BREAK) => {
try {
throw null;
}
catch (BALL) {
BREAK (BALL);
}
});
}
catch (BALL) {
console.log ("(A) BALL CAUGHT", BALL);
throw BALL;
}
}) ().
catch (BALL => {
console.log ("(B) BALL CAUGHT", BALL);
});
或者更简单地说,
(async () => {
await new Promise (async (FULFILL, BREAK) => {
try {
throw null;
}
catch (BALL) {
BREAK (BALL);
}
});
}) ().
catch (BALL => {
console.log ("(B) BALL CAUGHT", BALL);
});