【问题标题】:The first then for my promise returns a promise even though the rejected method has no return function in it即使被拒绝的方法中没有返回函数,我的承诺的第一个 then 也会返回一个承诺
【发布时间】:2018-09-26 08:12:17
【问题描述】:

在下面的代码中,链接到 addTwo 函数的第一个 .then() 调用了拒绝方法,因为我正在检查 a 和 b 的类型是否为“choco”,这是不可能的。

我希望输出停止在“我们有一个错误老板”而不继续,因为拒绝方法与解决方法不同,没有“返回 addTwo”语句。

但输出显示代码继续执行下一个 then 调用,输出为“第二次加法的答案:未定义”。为什么代码不只是在第一次 then 调用时停止,因为拒绝方法不返回 Promise?

var addTwo = (a, b) => {
    return new Promise((resolve, reject) => {   
        if(typeof a === choco && typeof b === choco){
            resolve(a + b)
        }else{
            reject("a or b or both were not numbers")
        }
    })
}


addTwo(5, 6).then((res) => {
    console.log("Answer of addition: " + res)
    return addTwo(res, 100)
}, (err) => {
    console.log("We have an error boss: " + err)
}).then((res) => {
    console.log("Answer of second addition: " + res)
}, (err) => {
    console.log("We have an error boss: " + err)
})

【问题讨论】:

  • 将第二个参数传递给a.then(...) 意味着:“如果a 被拒绝,则调用该函数并返回(成功)解决的承诺,如果没有抛出错误” .所以它完全按照设计工作。如果这不是您想要的行为,那么您不应该将第二个参数传递给 .then
  • “为什么代码不只是在第一次 then 调用时停止,因为拒绝方法不返回 Promise?” 你的意思是 rejectresolvereject 都不返回承诺。 new Promise.then 总是 返回一个承诺。一个promise可以处于三种不同的状态:“待定”,如果resolvereject都没有被调用,“已完成”如果resolve被调用,或者“被拒绝”如果reject被调用。你通过.then注册的函数在promise进入特定状态时被调用。这些函数中发生的事情决定了 .then 返回的承诺的状态。

标签: javascript node.js web es6-promise


【解决方案1】:

只有一个共同点。我已经更新了你的代码。

addTwo(5, 6).then((res) => {
    console.log("Answer of addition: " + res)
    return addTwo(res, 100);
}).then((res) => {
    console.log(res);
    console.log("Answer of second addition: " + res)
}).catch((err) => {
    console.log("We have an error boss: " + err)
})

【讨论】:

  • addTwo 返回一个承诺,所以你需要链接它
  • addTwo(res, 100) 被调用时,它将转到下一个。它只是被链接起来的,如果发生错误,就会有一个共同的问题。尝试在本地运行一次,无论是正确的还是错误的。
【解决方案2】:

您的代码中有两个错误,为了使其按预期工作,您需要这样编写:

    var addTwo = (a, b) => {
    return new Promise((resolve, reject) => {   
        if(typeof a === choco && typeof b === choco){
            resolve(a + b)
        }else{
            reject("a or b or both were not numbers")
        }
    })
}


addTwo(5, 6).then((res) => {
    console.log("Answer of addition: " + res);
    return addTwo(res, 100);
}, (err) => {
    console.log("We have an error boss: " + err);
    throw err;
}).then((res) => {
    res.then(res2) => {
        console.log("Answer of second addition: " + res2);
    }, (err) => {
        console.log("We have an error boss: " + err);
        throw err;
}})

【讨论】:

  • 这似乎不必要地复杂(最后一个throw err 没有正确传播到外部承诺链)。
【解决方案3】:

使用函数式风格和一些帮助程序,您可以以一种简单易读的方式解决这个问题:

import { curry } from 'crocks/helpers/curry'

// async functions always return promises
const addPromise = curry(async (a, b) => {
  if (typeof a !== 'number' || typeof b !== 'number') {
    throw new Error("a or b or both were not numbers")
  } else {
    return a + b
  }
})

const trace = tag => x => console.log(tag, x) || x

const handleError = err => console.log(`We have an error boss: ${err}`)

addPromise(5, 6)
  .then(trace('Answer from First Addition'))
  .then(addPromise(100))
  .then(trace('Answer from Second Addition'))
  .catch(handleError)

【讨论】:

    【解决方案4】:

    将 Promise 链视为具有两条链 - 已实现和已拒绝

    此外,您知道 .then 接受两个参数 .then(onFulfilled, onRejected) - 如果 onFulfilledonRejected 中的任何一个不是函数,则会被忽略

    .catch(fn) 只是.then(null, fn)

    .then(onFulfilled 或 onRejected)执行的每一个函数中,如果抛出错误,那么接下来会调用.thenonRejected——否则会调用onFulfilled下一个

    如果.then 的任何参数不是函数,.then 将忽略它们 - 在 onFulfilled 不是函数的情况下,.then 将返回一个已解决的 Promise,它采用已完成(已解决)的值 - 并且在 onRejected 不是函数的情况下,.then 将返回一个被拒绝的 Promise,它采用被拒绝的值

    您的代码是字面意思(只显示返回值,忽略 console.logs)

    addTwo(5, 6)
    .then(res => addTwo(res, 100), err => undefined)
    .then(res => undefined, err => undefined);
    

    由于第一个onRejected函数返回undefined,第二个.then(res=>将被调用

    正如另一个答案中所建议的那样,在这种情况下您需要一个 .catch

    所以

        addTwo(5, 6)
       .then((res) => {
            console.log("Answer of addition: " + res)
            return addTwo(res, 100)
        })
        .then((res) => {
            console.log("Answer of second addition: " + res)
        })
        .catch((err) => {
            console.log("We have an error boss: " + err)
        });
    

    这是 - 没有 console.logs

    addTwo(5, 6)
    .then(res => addTwo(res, 100), null)
    .then(res => undefined, null)
    .then(null, err => undefined);
    

    由于第一个和第二个 .then 对于onRejected 有空值,即不是一个函数,因此“错误”沿着被拒绝的链向下流动,直到“找到”一个函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 2015-06-05
      • 2017-08-19
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      • 2020-04-27
      相关资源
      最近更新 更多