【问题标题】:How can I promisfy these functions?我怎样才能承诺这些功能?
【发布时间】:2016-08-28 23:24:08
【问题描述】:

我正在使用 Node.js 和 Bluebird promises 库。

这段代码完全按照我想要的方式工作:

/*
 * Try using Bluebird promisify():
 * - "Good" case: this works perfectly.  
 *   ... but it DOESN'T use "promisify()"; it creates a new promise for each function.
 * - SAMPLE OUTPUT:
 *     callABC()...
 *     a():  [ 'a' ]
 *     b():  [ 'a', 'b' ]
 *     c():  [ 'a', 'b', 'c' ]
 *     Done: results: [ 'a', 'b', 'c' ] 
 */
var Promise = require('bluebird');

var a = function (results) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      results.push("a");
      console.log("a(): ", results);
      resolve(results);
    }, 15);
  });
}

var b = function (results) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      results.push("b");
      console.log("b(): ", results);
      resolve(results);
    }, 5);
  });
}

var c = function (results) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      results.push("c");
      console.log("c(): ", results);
      resolve(results);
    }, 10);
  });
}


var callABC = function (results) {
  console.log("callABC()...");
  a(results)
  .then(b)
  .then(c)
  .then(function (results) {
    console.log("Done: results:", results);
  })
  .catch(function (err) {
    console.log("Error:", err);
  });
}

callABC([]);

我知道像这样手动实例化您自己的 Promise 可能被认为是“不好的”:

问:我怎样才能“承诺”上面的 sn-p?

我尝试了很多东西;他们都没有工作。例如:

/*
 * Try using Bluebird promisify():
 * - Fails: never calls b() or c() 
 */
var Promise = require('bluebird');

var a = Promise.promisify(function (results) {
  setTimeout(function() {
    results.push("a");
    console.log("a(): ", results);
  }, 15);
});

var b = Promise.promisify(function (results) {
  setTimeout(function() {
    results.push("b");
    console.log("b(): ", results);
  }, 5);
});

var c = Promise.promisify(function (results) {
  setTimeout(function() {
    results.push("c");
    console.log("c(): ", results);
  }, 10);
});

var callABC = function (results) {
  console.log("callABC()...");
  a(results)
  .then(b)
  .then(c)
  .then(function (results) {
    console.log("Done: results:", results);
  })
  .catch(function (err) {
    console.log("Error:", err);
  });
}

callABC([]);

问:“承诺”第一个示例的正确方法是什么?

问:特别是,如果我用自动的Promise.promisify() 或Promise.promisifyAll() 代替手动的new Promise(),我如何“resolve()”或“reject()”我的回调?我想“投掷”会调用.catch(),但是还有另一种(更好的?)机制吗?

问:有什么限制吗?例如,函数是否需要有回调参数才能被“承诺”?

【问题讨论】:

  • promisify 不会变魔术。它仅适用于接受回调的函数。有关好的用例,请参阅 How do I convert an existing callback API to promises?。
  • 解决这个特殊问题的正确方法是使用Promise.delay,这是setTimeout 的承诺版本。试试看。
  • @Bergi: 1) 这是我一直在寻找的答案“promisify 不会变魔术。它只适用于需要回调的函数”。 2)谢谢你的链接。 3) "setTimeout()" 仅用于测试目的;它与实际问题无关。 4)如果您想将您的评论放在“答案”中,我很乐意“接受”它。

标签: node.js promise bluebird


【解决方案1】:

答案是:“不是所有的 JS 函数都可以被承诺”。具体来说:

http://bluebirdjs.com/docs/api/promise.promisify.html

Promise.promisify)... 返回一个将包装给定的函数 节点函数。返回的函数不是回调,而是 返回一个 Promise,其命运由 给定节点函数。节点功能应符合 node.js 接受回调作为最后一个参数并调用它的约定 以错误作为第一个参数和成功值的回调 第二个参数。

所以在上面的示例中,“new Promise”是正确的方法:“Promise.promisify()”将不起作用。

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 2021-04-01
    • 2021-06-07
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2022-12-09
    相关资源
    最近更新 更多