这对异步转换的承诺正确吗,为什么不需要等待?

时间:2018-10-18 05:46:01

标签: node.js async-await

我对这段代码有一个承诺。

function f (number) {
  return new Promise((resolve, reject) => {
    if (number === 42) {
      resolve({ success : "bar" })
    }

    reject({ bar : "foo" })
  })
}

f(42)
  .then(success)
  .catch(bar);

f(43)
  .then(success)
  .catch(bar);

function success(input) {
  console.log(input)
}

function bar() {
  console.log("marianna")
}

及其后面的尝试将诺言转换为异步/等待语法的尝试:

async function f (number) {
    if (number === 42) {
      return { success : "bar" }
    }

    throw { bar : "foo" }
}

f(42)
  .then(success)
  .catch(bar);

f(43)
  .then(success)
  .catch(bar);

function success(input) {
  console.log(input)
}

function bar() {
  console.log("marianna")
}

两个脚本给出的输出相等。我认为转换是正确的,但是“读取”异步代码仍然很困难。

无论如何,..为什么没有必要等待?什么时候需要等待?

3 个答案:

答案 0 :(得分:1)

await可以改善代码阅读。它对待asynchronous函数调用看起来像synchronous调用。

在您的示例中,假设我想在f(43)之后运行f(42)。对于这种情况,我可以在下面这样做

f(42)
  .then(() => {
    success(); 
    return f(43);
  })
  .then(success) 
  .catch(bar);

await

相比

async function f (number) {
    if (number === 42) {
      return { success : "bar" }
    }

    throw { bar : "foo" }
}

async function run() {
  try {
    const result42 = await f(42); // async function but called like sync function
    success(result42); 
    
    const result43 = await f(43);
    success(result43);
  } catch(error) {
    bar(error);
  }
}

run();

function success(input) {
  console.log(input)
}

function bar() {
  console.log("marianna")
}

答案 1 :(得分:0)

Promise是一个对象,代表异步操作的最终完成或失败。

您的代码中没有异步的东西,函数f()的两个版本都返回一个已经解决或拒绝的Promise。但是,这不会改变async/await的工作方式。

使用asyncawait,您的代码应如下所示:

async function f (number) {
    if (number === 42) {
      return { success : "bar" }
    }

    throw { bar : "foo" }
}

try {
    res = await f(42)
    success(res)
} catch(err) {
    bar(err);
}

try {
    res = await f(43)
    success(res)
} catch(err) {
    bar(err);
}

function success(input) {
  console.log(input)
}

function bar(err) {
  console.log(`error: ${err}`)
}

在后台,两个版本的代码以相同的方式运行。但是通常async / await版本更易于阅读,因为代码的布局与同步代码相同,而await位于异步操作的前面。

答案 2 :(得分:0)

  

我认为转换是正确的,但是我仍然难以“读取”异步代码。

在决定async/awaitthen/catch语法时,我有两件事需要考虑:

  1. 它应在NodeJS低于7.6版的安装上运行吗?如果是,我们只能使用Promise then/catch,因为async/await从v7.6 NodeJS 7.6 support for async/await开始。
  2. 哪个版本的用户可以阅读清洁我的代码?

当我认为一段代码会在一个async/await块中将清洁程序读为一系列过程时,我会使用try/catch

async-await-test.js

main()

/* test body */
async function main() {
  try {
    const result = await pingMeAfterOneSecond(true)
    console.log('RESOLVED with ', result)
  } catch (e) {
    console.log('REJECTED due to', e)
  }
}

/* some function that will resolve or reject as requested after 1 second -- this is same as in then-catch-test.js */
function pingMeAfterOneSecond(willSucceed) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (willSucceed) {
        resolve(true)
      } else {
        reject(false)
      }
    }, 1000)
  })
}

当我认为一段代码可能会看起来像then/catch个块的嵌套意大利面条的危险时,我会使用try/catch

then-catch-test.js

/* test body */
pingMeAfterOneSecond(true)
  .then(result => console.log('RESOLVED with ', result))
  .catch(e => console.log('REJECTED due to', e))

/* some function that will resolve or reject as requested after 1 second -- this is same as in try-catch-test.js */
function pingMeAfterOneSecond(willSucceed) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (willSucceed) {
        resolve(true)
      } else {
        reject(false)
      }
    }, 1000)
  })
}

希望这可以帮助您对选择进行思考。干杯,