我以后如何检索promise的结果?在一次测试中,我在发送进一步请求之前检索了一封电子邮件:
const email = await get_email();
assert.equal(email.subject, 'foobar');
await send_request1();
await send_request2();
如何在缓慢的电子邮件检索过程中发送请求?
起初,我考虑过以后再发邮件:
// This code is wrong - do not copy!
const email_promise = get_email();
await send_request1();
await send_request2();
const email = await email_promise;
assert.equal(email.subject, 'foobar');
如果get_-email()
成功,则此操作有效,但如果get_-email()
在相应的等待
之前失败,并且出现完全正确的未处理PromisejectionWarning
,则此操作失败。
当然,我可以用promise。全部
,如下所示:
await Promise.all([
async () => {
const email = await get_email();
assert.equal(email.subject, 'foobar');
},
async () => {
await send_request1();
await send_request2();
},
]);
然而,这使得代码更难阅读(它看起来更像基于回调的编程),特别是如果以后的请求实际上依赖于电子邮件,或者有一些嵌套正在进行。有没有可能存储promise的结果/异常,并在以后等待它?
如果需要的话,这里有一个模拟的测试用例,有时失败,有时工作,随机计时。它绝不能输出未经处理的PromiserEjectionWarning。
所以,我想解释一下为什么我们在节点中会这样做。js:
// Your "incorrect code" from before
const email_promise = get_email(); // we acquire the promise here
await send_request1(); // if this throws - we're left with a mess
await send_request2(); // if this throws - we're left with a mess
const email = await email_promise;
assert.equal(email.subject, 'foobar');
也就是说,我们这样做的原因是不处理“多次拒绝,可能没有清理”的场景。我不知道你是如何得到Promise.all
的长代码的,但是:
await Promise.all([
async () => {
const email = await get_email();
assert.equal(email.subject, 'foobar');
},
async () => {
await send_request1();
await send_request2();
},
]);
实际上可以是这样的:
let [email, requestData] = await Promise.all([
get_email(),
send_request1().then(send_request2)
]);
// do whatever with email here
我可能会这么做。
如果保证稍后会处理promise拒绝,则可以使用dummycatch
链接promise,以抑制未处理拒绝的检测:
try {
const email_promise = get_email();
email_promise.catch(() => {}); // a hack
await send_request1();
await send_request2();
const email = await email_promise;
assert.equal(email.subject, 'foobar');
} catch (err) {...}
这种方法的问题是,有两个并发例程,但代码没有表达这一点,这是一种解决方法,通常使用Promise来完成。全部
。这种变通方法之所以可行,唯一的原因是只有两个例程,其中一个(get_email
)需要与链接,然后
/wait
,只有一次,所以其中的一部分(assert
)可以推迟。如果有3个或3个以上的例程,或者例程涉及多个,那么
/等待
,问题就会更加明显。
以防promise。所有
都引入了不需要的lambda嵌套级别,这可以通过将例程编写为命名函数来避免,即使它们没有在其他地方重用:
async function assertEmail() {
const email = await get_email();
assert.equal(email.subject, 'foobar');
}
async function sendRequests() {
await send_request1();
await send_request2();
}
...
try {
await Promise.all([assertEmail(), sendRequests()]);
} catch (err) {...}
这会产生干净的控制流和冗长但更易于理解和测试的代码。
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const send_request1 = () => wait(300), send_request2 = () => wait(200);
async function get_email() {
await wait(Math.random() * 1000);
if (Math.random() > 0.5) throw new Error('failure');
return {subject: 'foobar'};
}
const assert = require('assert');
async function main() {
// catch possible error
const email_promise = get_email().catch(e => e);
await send_request1();
await send_request2();
// wait for result
const email = await email_promise;
// rethrow eventual error or do whatever you want with it
if(email instanceof Error) {
throw email;
}
assert.equal(email.subject, 'foobar');
};
(async () => {
try {
await main();
} catch(e) {
console.log('main error: ' + e.stack);
}
})();
我编写了一个函数,它返回异步逐行读取文件的promise,但问题是如果文件不存在,就会抛出错误,应用程序崩溃。我已经将代码包围在try-catch块中,但是代码执行从未进入catch块,而是终止。 其次,我可以拒绝promise,然后从promise中返回json对象吗? 像
我在想什么时候我该拒绝一个promise。我发现了几个关于这个话题的问题,但找不到合适的答案。我什么时候应该拒绝promise? 本文http://howtonode.org/6666a4b74d7434144cff717c828be2c3953d46e7/promises 说: 解析:一个成功的promise是“已解析”的,它调用正在等待的成功侦听器,并记住为附加的未来成功侦听器解析的值。分辨率
我正在使用Firebase云消息服务辅助角色处理后台推送通知。 当通知(其中包含一些数据的URL)被点击,我想要么: 焦点窗口,如果它已经在所需的URL 导航到URL并聚焦它,如果已经有一个活动的选项卡打开 如果上述条件都不满足,则打开URL的新窗口 点1和3与下面的SW代码一起工作。 出于某种原因,第2点不起作用。promise被拒绝,原因是: 我认为这可能是由于缺少https,但从我的阅读来看
本文介绍了单个promise组合器: 但我没有看到的是,一种运行所有promise的方法,但不是在个人promise被拒绝时短路。我如何确保所有的promise都得到履行,但我能处理拒绝和所有promise的解决?
我得到这个错误- (节点:18420)未处理的PromisejectionWarning:TypeError:无法读取未定义的属性“name” (节点:18420)未处理的PromisejectionWarning:未处理的promise拒绝。此错误源于在没有catch块的情况下抛出异步函数的内部,或者拒绝使用未处理的promise。catch()。要在未处理的promise拒绝时终止节点进程,请
我正在尝试编写一个jasmine测试,它有一个间谍, 是一个许诺列表。前几次承诺是拒绝,最后一次是成功。虽然测试顺利通过,但Node抱怨如下: 我的代码非常直接:我创建一个间谍,将它注入到我的代码中,调用我的代码,这将循环调用我的间谍直到它不拒绝,然后监视它被调用了5次。间谍是这样的: 被测试的代码在它的链中最后一个空的 来验证我没有引起那里的问题。AFICT,问题是Node看到我在执行 ,并认为