- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在浏览并尝试熟悉 Promise,我将跳过介绍性概念,并深入了解问题的实质。在 NodeJS 中,使用库 BlueBird 。我不想推迟函数调用,我也不想过多地污染代码,即使这是熟悉前提的介绍性编码,因为当尝试更高级的概念时,我会得到迷失在他们身上。我尝试将“asyn/await”与 try block 一起使用,但上帝是代码困惑,并且不起作用......或多或少的指导方针:
Promise 包含内置的 catch 机制,如果处理标准的单个 Promise,该机制可以完美地工作。
// Try/Catch style Promises
funcTwo = function(activate) {
return new Promise(function(resolve, reject) {
var tmpFuncTwo;
if (activate === true) {
tmpFuncTwo = "I'm successful"
resolve(tmpFuncTwo)
} else if (activate === false) {
tmpFuncTwo = "I'm a failure.";
reject(tmpFuncTwo)
} else {
tmpFuncTwo = "Oh this is not good."
throw new Error(tmpFuncTwo);
}
});
}
funcTwo(true)
.then(val => {
console.log("1: ", val)
return funcTwo()
})
.catch(e => {
console.log("2: Err ", e.message)
})
让我有些困惑的是试图坚持与 Promise.all 相同的前提,错误没有被处理,因为抛出直接推送到主 Controller 。从此代码段引发的异常永远不会进入 Catch block 。
funcThree = function(val) {
return new Promise(function(resolve, reject) {
if (val > 0)
resolve((val + 1) * 5)
else if (val < 0)
reject(val * 2)
else
throw new Error("No work for 0");
})
}
// Output in Dev Console
/*
Extrending to the catch block handling, This will fail, the exception is thrown, and ignores the catch block. Terminating the program.
*/
Promise.all([funcThree(1), funcThree(0), funcThree(-3)])
.then(function(arr) {
for (var ind = 0; ind < arr.length; ind++) {
console.log(arr)
};
}, function(arr) {
console.log(arr)
})
.catch(function(e) {
console.log("Error")
})
我尝试了一种简单的解决方法,但我对这门语言有点陌生,并且不确定这是否遵循“最佳实践”,因为它们是从 Python 指南中灌输到我的脑海中的。
// Promise all, exceptionHandling
funcThree = (val) => {
return new Promise(function(resolve, reject) {
if (val > 0)
resolve((val + 1) * 5)
else if (val < 0)
reject(val * 2)
else {
var tmp = new Error("No work for 0");
tmp.type = 'CustomError';
reject(tmp);
}
})
}
/*
This works, and doesn't cause any type of mixup
*/
Promise.all([funcThree(1), funcThree(0), funcThree(-3)])
.then(
arr => {
for (var ind = 0; ind < arr.length; ind++) {
console.log(arr)
};
}, rej => {
if (rej.type == 'CustomError')
throw rej;
console.log(arr)
})
.catch(e => {
console.log("Catching Internal ", e.message)
})
这是使用 Native Promise 库以及 bluebird
有没有一种方法可以更本地化地处理这个问题,
关于jfriend00的评论。我的意思是说,我不希望异常由 try-catch block 之外的任何东西处理。当我尝试使用与正常 promise 相同的格式时,一切都完美对齐,并且我的捕获得到确认,错误得到处理。由于 Promise.all 只能解析/拒绝,我认为没有一种干净的方法来委托(delegate)第二个代码片段中第二次调用 funcTwo 引发的异常。或多或少我不确定我所做的解决方法是否是一个好的解决方案,或者是否会导致一些深层问题随着代码的扩展。
最佳答案
Since Promise.all can only ever resolve/reject I don't think that there is a clean way of delegating the exception that is thrown from the second call to funcTwo in the second code snippet.
在您的这个代码块中:
// Try/Catch style Promises
funcTwo = function(activate) {
return new Promise(function(resolve, reject) {
var tmpFuncTwo;
if (activate === true) {
tmpFuncTwo = "I'm successful"
resolve(tmpFuncTwo)
} else if (activate === false) {
tmpFuncTwo = "I'm a failure.";
reject(tmpFuncTwo)
} else {
tmpFuncTwo = "Oh this is not good."
throw new Error(tmpFuncTwo);
}
});
}
throw
和 reject()
之间没有区别。 throw
被 Promise 构造函数捕获并转换为 reject()
。就我个人而言,我更喜欢在这种情况下仅使用 reject()
,因为我认为函数调用比异常要快一些。
我不知道这是否已编入规范,但通常认为使用 Error 对象拒绝是一个好主意。所以,我会像这样编写代码:
function funcTwo(activate) {
return new Promise(function(resolve, reject) {
if (activate === true) {
resolve("I'm successful");
} else {
let errMsg = activate === false ? "I'm a failure." : "Oh this is not good.";
reject(new Error(errMsg));
}
});
}
Promise 要么解决,要么拒绝。没有与拒绝不同的第三种错误情况。异常(exception)只会变成拒绝。因此,如果您要返回三种状态(如上面的代码),那么您必须决定如何将这三种状态放入 resolve
和 reject
。
由于这只是示例代码,因此这里没有具体的建议。如果 activate === false
实际上不是一个错误,只是一种不同类型的完成,不应该中止 Promise.all()
中的其他 promise ,那么你' d 希望该情况为 resolve()
,而不是 reject()
。但是,没有硬性规定什么是什么 - 它实际上只取决于您希望调用者的行为变得自然和简单,因此它会因情况而异。
此外,如果您不控制这里的 funcTwo
中的代码,那么您可以在传递之前在其上放置一个 .catch()
处理程序它到 Promise.all()
并且您可以将特定的拒绝转换为解决方案(如果您希望 Promise.all()
逻辑以这种方式工作)。 promise 链,以便您可以在将它们传递到更高级别的操作之前修改它们的输出。它类似于在较低级别使用 try/catch 来捕获异常并处理它,因此较高级别的代码不必看到它(有时是适当的)。
More or less I'm not sure if what I've done as a workaround," reject, check if reject passed forward an error, and then throw it if it did", is a good solution or if it will cause some deep problem as code expands.
在您的 Promise.all()
代码中:
/*
This works, and doesn't cause any type of mixup
*/
Promise.all([funcThree(1), funcThree(0), funcThree(-3)]).then(arr => {
for (var ind = 0; ind < arr.length; ind++) {
console.log(arr[index]);
}
}, rej => {
if (rej.type == 'CustomError')
throw rej;
console.log(arr)
}).catch(e => {
console.log("Catching Internal ", e.message)
})
您的第一个拒绝处理程序并没有真正帮助您。它不会做任何您在一个 .catch()
处理程序中无法完成的事情。让我重复一遍。 Promise 仅有两个结果 reject
和 resolve
。异常(exception)情况没有第三种结果。 Promise 回调中发生的异常只会变成拒绝。因此,您上面的代码可以更改为:
/*
This works, and doesn't cause any type of mixup
*/
Promise.all([funcThree(1), funcThree(0), funcThree(-3)]).then(arr => {
for (var ind = 0; ind < arr.length; ind++) {
console.log(arr)
};
}).catch(e => {
// there is no value for arr here, no result - only a reject reason
console.log("Catching Internal ", e.message)
if (rej.type === "CustomError") {
// do something special for this type of error
}
// unless you rethrow here, this rejection will be considered handled
// and any further chained `.then()` will see the promise as resolved
// but since there is no return value, the promise will be resolved
// with an undefined result
});
如果您想尽早捕获 funcThree()
中的拒绝,以便仍可以跟踪 Promise.all()
中的其余 Promise,并且仍然得到他们的结果,那么你可以得到一个 Promise.settle()
实现,它将遵循所有的 promise 来得出结论,无论有多少拒绝,或者你可以编写自己的特殊情况:
function funcFour(val) {
return funcThree(val).catch(err => {
// catch and examine the error here
if (err.type === "CustomError") {
// allow things to continue on here for this specific error
// and substitute null for the value. The caller will have
// to see null as a meaningful result value and separate from
// a non-null result
return null;
} else {
// Not an error we recognize, stop further processing
// by letting this promise reject
throw err;
}
});
}
Promise.all([funcFour(1), funcFour(0), funcFour(-3)]).then(arr => {
// got results, some might be null
console.log(arr);
}).catch(err => {
// got some error that made it so we couldn't continue
console.log(err);
});
<小时/>
我知道这都是风格观点,但是使用 Promise 的良好代码的好处之一是,您不再需要深缩进的代码,现在我看到人们添加了各种额外的缩进和根本不需要的行,并且似乎消除了干净 promise 编码的一些好处。
在这种情况下,.then()
和 .catch()
可以与它们遵循的 Promise 位于同一行。而且,无需在新行上开始内联函数定义。
关于javascript - Promise.all 与 try/catch 模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42739883/
如何从 promise 中退出 promise ? perl6 文档没有提供简单的方法。例如: my $x = start { loop { # loop forever until "qui
我的用户 Controller 中有一个索引操作,其中我试图连续做两件事,并且在它们都有机会完成之前不执行所需的 res.json() 方法。 我有一个加入用户的友谊加入模型。一列是 friender
请帮我解释一下为什么日志结果有两种不同: 方式 1:每 1 秒顺序记录一次 方式 2:1 秒后记录所有元素。 // Way 1 let sequence = Promise.resolve(); [1
我的问题很简单。 Promise.all() 方法可以返回 Promise 吗?让我解释一下: function simpleFunction() { let queue = [];
我正在使用 Promise 从存储中读取文件并转换为 base64 字符串。我有图像数组,使用 RNFS 读取图像 const promise_Images = _Images.map(async (
如果使用非空数组调用 Promise.all 或 Promise.race,它们将返回一个待处理的 Promise: console.log(Promise.all([1])); // prints
Promise.all 是否可以在没有包装 promise 的情况下返回链的最后一个值? 如果不使用 await,它在我的上下文中不起作用 没有包装的例子: function sum1(x){ r
我一直在玩 promise,通常能想出如何处理好它们,但在这种情况下,我不知道如何删除一个 promise-wrapping level。 代码如下: let promise2 = promise1.
考虑以下嵌套的Promises结构: const getData = async() => { const refs = [{ name: "John33", age: 3
我已经阅读了 Promise/A+ 规范,但据我了解,还有诸如 Promise/A 和 Promise 之类的东西。它们之间有什么区别? Promise 和 Promise/A 规范也是如此吗?如果是
当我运行以下代码时: my $timer = Promise.in(2); my $after = $timer.then({ say "2 seconds are over!"; 'result'
以下简单的 promise 是发誓的,我不允许打破它。 my $my_promise = start { loop {} # or sleep x; 'promise re
我正在尝试扩展Promise: class PersistedPromise extends Promise { } 然后在派生类上调用静态resolve以直接创建一个已解决的Promise: Per
我有两个返回 promise 的函数,我独立使用它们作为: getLocal().then(...) 和 getWeb().then(...) 但是现在我遇到了一个奇怪的问题: 1) 我需要第三个
我不知道 promise.all 解决方案中的 promise.all 是否是一个好的实践。我不确定。 我需要从一组用户获取信息,然后通过此信息响应,我需要发送消息通知。 let userList =
我一直在尝试使用 queueMicrotask() 函数,但我没有弄清楚当回调是微任务时回调的优先级如何。查看以下代码: function tasksAndMicroTasks() { const
我一直在尝试使用 queueMicrotask() 函数,但我没有弄清楚当回调是微任务时回调的优先级如何。查看以下代码: function tasksAndMicroTasks() { const
今年早些时候,我在 Pharo Smalltalk 参与了一个 promise 项目。这个想法是为了实现以下行为: ([ 30 seconds wait. 4 ]promiseValue )then:
大家好,提前感谢您的帮助。 下面是我正在尝试做的事情 function1(){ throw some error(); } function2() { // dosomething suc
我有以下未解析的代码。f2 解决了,所以我不会添加该代码,它是 f1 我有问题。 我调用函数,它到达最里面如果,它调用函数“find”,它执行函数 findId,完美返回 Id,然后执行 editId
我是一名优秀的程序员,十分优秀!