Promise((resolve, reject) => {})和Promise(resolve => {})之间有什么区别?

5

我们知道Promise构造函数接受一个执行器函数,该函数有两个参数,我们用它来生成成功或失败的情况。今天我在编程时遇到了问题,但后来解决了,但我发现需要理解一件事情。

以下是两种方式的区别:

new Promise(resolve => {

    // resolve

});

并且

new Promise((resolve,reject)=>{

    // resolve
    // reject

});

我们可以这样做吗?

new Promise(resolve => {

    // resolve

}, reject => {

    // reject

});

示例会更加受欢迎。谢谢 !!!

2
我们可以这样做吗?不行。 - Jonas Wilms
1
@JonasWilms - 现在有一件事情是清楚的。谢谢 :) - user10220492
你不能分离resolve和reject操作,两者都应该在同一个上下文中使用,(resolve, reject)是回调变量,应该在同一个函数中使用以执行这些回调。 - Julian Torregrosa
可能是Promise:then vs then + catch的重复问题。 - Alexander
4个回答

5
这不仅适用于Promise,也适用于回调函数。 new Promise((resolve) => {});1创建一个只有一个参数resolve的Promise回调函数,无法调用否则提供的reject函数。2 new Promise((resolve, reject) => {});创建一个带有两个参数的Promise回调函数,包括一个用于拒绝的参数。
上述两个示例演示了位置参数的工作原理。回调函数中的第一个参数始终是resolve函数,第二个参数始终是reject函数。 new Promise((reject, resolve) => {});将创建一个Promise,在其中您可以使用reject解决问题,并使用resolve拒绝。
您可以在回调函数的范围内throw或者resolve(Promise.reject())来引发拒绝:
new Promise((resolve) => {
  throw new Error("42");
  // or `resolve(Promise.reject(new Error("42")));`
})
  .catch(console.warn); // Prints warning “Error: "42"” in the console.

您不能使用new Promise((resolve) => {}, (reject) => {});,因为Promise构造函数只接受一个参数。第二个回调函数将被忽略。

1: 当然,(resolve) => {}等同于resolve => {}。但是箭头函数参数实际上总是需要括号。简单和单一参数是唯一的例外,可以省略它们。请参阅MDN关于箭头函数语法的文章

2: 使用常规函数new Promise(function(resolve){});new Promise(function(){});,您可以通过arguments[0]resolve)或arguments[1]reject访问任何参数


1b) 当回调函数内有人“throw”,或者使用resolve(Promise.reject())时。 - Jonas Wilms
如果我这样做 **new Promise(resolve,reject => {})**,这样正确吗? - user10220492
@DhuBytes 如果你有多个参数,例如 **(resolve, reject) => {}**,你需要使用 () 将它们包装起来。 - Koushik Chatterjee
@DhuBytes 不是这样的。箭头函数参数总是需要用括号括起来,除非只有一个参数。new Promise(resolve, reject => {}) 是一个使用现有变量 resolve 作为执行器的 Promise,并将忽略 (reject) => {} 函数。 - Sebastian Simon
这意味着当我们像这样做 abc => {} 时,它意味着 abc 是函数参数。如果我们需要多个参数,我们必须像这样做 **(abc,def,...) => {}**。因此,在一个参数的情况下,可以省略括号,但在多个参数的情况下,需要使用括号。对吗? - user10220492
@DhuBytes 是正确的,但情况并不止于此。参数也可以是剩余参数或解构参数,如 (...array) => {}, ([{value: renamed} = object]) => {}。这些被称为“非简单参数”,它们都需要括号。 - Sebastian Simon

2

如果您确定 Promise 永远不会失败,例如定时器,可以省略 reject。但是任何需要错误处理程序(如 http 请求、文件 I/O 等)的操作都需要使用 reject 回调函数。


1
好的,所以如果我们传递一个函数,那么它将被视为 Promise 构造函数中的 resolve 函数? - user10220492
是的,传递到Promise构造函数中的函数的第一个参数是resolve处理程序。第二个参数(reject处理程序)是可选的。 - TLP
那如果我这样写 new **Promise(resolve,reject => {})**,这样正确吗? - user10220492
你需要在 resolve,reject 周围加上一些括号,但是除此之外很好(当然假设你会在 {} 之间放置一些代码)。所以:new Promise((resolve,reject) => { resolve(getSomeValue()); }) - TLP
这意味着当我们像这样做 abc => {} 时,它意味着 abc 是函数参数。如果我们需要多个参数,我们必须像这样做 **(abc,def,...) => {}**。因此,在一个参数的情况下,可以省略括号,但在多个参数的情况下,需要使用括号。对吗? - user10220492

0

箭头函数是异步操作结束时触发的回调函数。它接受两个参数,成功时要调用的函数(resolve)和失败时要调用的函数(reject)。

在JS中,您不必将所有参数传递给函数回调。如果您不打算处理错误(您应该处理!),则可以省略它。

如果您传递1个参数,则被视为resolve函数。


0

好的,在JavaScript标准中,如果任何具有一个参数的函数被调用时带有两个参数,那么忘记Promise也没有问题(反之亦然)。

现在,针对您的promise,您传递给构造函数的回调将使用2个参数调用(解析器函数和拒绝器)。如果您创建一个具有1个参数的函数并将其传递给Promise的构造函数,则它将简单地通过2个参数进行调用,因为您没有引用第二个参数,所以无论如何都不能将其用作应该被用户使用的方式(作为一般语句而不是Promise)。

如果仍然需要第二个参数,您仍然可以尝试使用arguments,但是使用箭头函数也不会得到它。在这种情况下,最好使用普通的function () {}。否则,您可以尝试使用Promise.resolvePromise.reject显式返回另一个promise。

毫无疑问,最后一个具有多个回调作为参数传递给Promise构造函数的方法是行不通的,因为它们像只有一个带有2个参数的回调一样进行设计。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接