【问题标题】:Non-async promise callbacks [duplicate]非异步承诺回调[重复]
【发布时间】:2015-09-11 20:36:52
【问题描述】:
function foo(options) {
  var deferred = q.defer();
  nonPromisifiedApi(options, deferred.resolve, deferred.reject);
  return deferred.promise;
}

function bar() {}

function bam() {}

foo({})
  .then(bar)
  .then(bam);

nonPromisifiedApi 完成其异步工作后,在依次调用barbam 时,此代码是否会按预期工作?

【问题讨论】:

  • 你测试了吗?看起来,bar 将执行 - 然后 bam 将执行但它们之间没有承诺.. 所以当 bam 运行时,bar 不能保证完成!
  • 您的评论“您测试过吗”可以应用于本站 50% 的 cmets。我刚刚对其进行了测试,并将我的发现添加到答案中。你评论的其余部分是完全错误的。
  • 您的 deferred.resolvedeferred.reject 作为未绑定到实际延迟对象的函数传递。 bar 和 bam 也将被一一执行,之间没有任何延迟
  • 感谢您强调绑定问题。但是,鉴于它“有效”,我怀疑 q 是否为了方便而预先绑定了函数。
  • 另外,请注意 defer 的使用是非标准的,现在被认为是不好的做法。您可以考虑使用Q.Promise api 的可能性。更好的是,您可以使用 ES6 polyfill 而不是 Q(例如 github.com/jakearchibald/es6-promise)。这是一篇关于承诺的好文章:pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html。阅读它可能会回答您可能遇到的大部分问题。

标签: javascript promise q


【解决方案1】:

这是一个 sn-p,向您展示它运行良好(使用我建议您的语法)。

function log(msg){ document.body.innerHTML += "<p>" + msg + "</p>"; }

function nonPromisifiedApi(options, fail, callback){
  log("nonPromisifiedApi");
  setTimeout(function(){
    callback("nonProm's async result");
  }, options.time);
}

function async(options){
  return Q.Promise(function(resolve, reject){
    nonPromisifiedApi(options, reject, function(val){
      log("async (val: " + val + ")");
      resolve("async's result");
    });
  });
}

function sync1(val){
  log("sync1 (val: " + val + ")");
  // filters the returned value
  return "sync1's result";
}

function sync2(val){
  log("sync2 (val: " + val + ")");
  // no return => undefined
}

async({time: 1000})
  .then(sync1)
  .then(sync2)
  .then(function(val){
     log("end (val: " + val + ")")
  });
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.4.1/q.min.js"&gt;&lt;/script&gt;

再一次,您不会在阅读this article about promises 时浪费时间。

而且我认为使用 ES6 Promise polyfill 而不是 Q 可能是更好的选择。

【讨论】:

  • 在非承诺异步函数的 API 与 resolve, reject 约定不匹配的极少数情况下,延迟概念仍然有一个用例? ES6 Promise 标准是否公开了延迟的概念?
  • 比我更专业的人可能会告诉你,他从未遇到过需要延期的情况。这个想法是你在承诺的“身体”中做你的事情。我已经更新了我的 sn-p,以便更好地反映您的用例。
  • 哦,不,标准 API 中没有 deferred 之类的东西。
【解决方案2】:

是的,它会按预期工作。 q 按顺序处理未承诺的同步函数(如预期的那样),通过将它们静默地包装在单子 API 中。

【讨论】:

    猜你喜欢
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2019-01-15
    • 2019-03-10
    • 2018-03-02
    • 2018-09-02
    相关资源
    最近更新 更多