如何实现回调?

时间:2020-10-11 06:03:21

标签: javascript node.js ecmascript-6 promise

如何在getValue1函数中实现回调?

现在我变得不确定了吗?

我需要在getAll函数中获取“ B”值

getAll函数需要返回一个Promise,并且getValue1函数不能更改。我该怎么做?

function getValue1(callback) {
  setTimeout(() => {
      callback("B");
  }, 10);
}

function getAll() {
   return Promise.all([getValue1(b => b)]);
}

getAll().then((arr) => console.log(arr));

2 个答案:

答案 0 :(得分:2)

创建一个函数来包装对getValue1的调用,使之解析为回调返回的值

const pvalue = () => new Promise(resolve => getValue1(resolve));

注意,这与

相同
function pvalue() {
  return new Promise(function(resolve) {
    getValue1(value => resolve(value));
  });
}

所以, 值=> resolve(值)

您是对getValue1的回调-解决pvalue返回的Promise吗?

当然,

getValue1(value => resolve(value));

等同于

getValue1(resolve);

因此,您可以在pvalue()中呼叫getValue1(b=>b)而不是Promise.all

function getValue1(callback) {
    setTimeout(() => {
        callback("B");
    }, 10);
}
const pvalue = () => new Promise(resolve => getValue1(resolve));

function getAll() {
    return Promise.all([pvalue()]);
}

getAll().then((arr) => console.log(arr));

答案 1 :(得分:0)

Continuation-passing style(即“回调”)和Promises是用于处理异步代码的两种不同类型的机制。从历史上看,JavaScript和Node使用函数回调,并且程序员应遵循某些约定来编写其代码。由于很难遵循未强制执行的约定,因此编写回调代码非常容易出错。 Promises是一种更新的一流数据结构,它提供了专门为处理异步而设计的更多功能。


如果您编写getValue1,

JavaScript社区已经广泛接受了Promises,并且为该语言添加了更多功能以利用它们的普遍性。您应该尽可能地编写基于Promise的代码。这意味着如果 you getValue1的作者,则不应进行回调,而应返回promise-

const delay = (ms, value) =>
  new Promise(r => setTimeout(r, ms, value))

const getValue1 = _ =>
  delay(2000, "B")

getValue1().then(console.log, console.error)

console.log("please wait...")

如果愿意,可以使用连续传递样式编写getValue1。 Node.js使用约定,其中任何错误(如果存在)将是回调的 first 参数。在Node中,您必须始终检查回调中是否存在错误,否则可能会在程序中引入错误。要遵循此约定,您的代码应类似于-

const getValue1 = (callback) =>
  setTimeout(_ => callback(null, "B"), 2000)

getValue1((err, res) => {
  if (err)
    console.error("error encountered:", err.message)
  else
    console.log("result:", res)
})

console.log("please wait...")


如果您继承getValue1,

当您继承回调样式函数时,对其进行转换很有用,因此可以将其与基于Promise的新代码一起使用。为此,Node.js具有内置功能util.promisify。出于演示目的,我在下面的示例中添加了自己的promisify-

const promisify = f => (...a) =>              // <- util.promisify
  new Promise
    ( (resolve, reject) =>
        f(...a, (e, v) => e ? reject(e) : resolve(v))
    )

const getValue1 = (callback) =>               // <- old code
  setTimeout(_ => callback(null, "B"), 2000)

const _getValue1 =
  promisify(getValue1)                        // <- promisify old code
  
_getValue1().then(console.log, console.error) // <- back to sanity

console.log("please wait...")


兑现承诺

Promise可让您利用asyncawait之类的新语言功能,从而大大改善代码的读写体验-

const sleep = ms =>
  new Promise(r => setTimeout(r, ms))

async function getValue1 ()
{ await sleep(1000)
  console.log("loading: 25%...")
  await sleep(1000)
  console.log("loading: 50%...")
  await sleep(1000)
  console.log("loading: 75%...")
  await sleep(1000)
  return "B"
}

async function main()
{ console.log("please wait...")
  const result = await getValue1()
  console.log("done:", result)
}

main().catch(console.error)

please wait...
loading: 25%...
loading: 50%...
loading: 75%...
done: B