【问题标题】:Value returned using deferred.resolve(value) to my .then() is undefined使用 deferred.resolve(value) 返回到我的 .then() 的值未定义
【发布时间】:2016-07-11 11:11:54
【问题描述】:

我使用 Q.js 调用一个 api 在我的 main 函数中使用如下两个循环

    for i..10
     for i...5
         var promise = getLoc(x,y);
         promise.then(function(value) {
             //value is undefined...
         }

在我的 getLoc 函数中,我有

    function getLoc(x,y) {
      var value;
      var deferred = Q.defer();
      Q.ninvoke(request, 'get', {

      }).spread(function(response, body) {
        value = body;
      });

      defferred.resolve(value);
      return deferred.promise
    }

为什么我传递给 then 函数的值没有定义?如何传递我的解析值?谢谢!

【问题讨论】:

标签: javascript node.js asynchronous q deferred


【解决方案1】:

您必须在异步回调中调用 resolve(),因为该回调会在未来某个时间被调用,所以这是唯一知道值的地方:

function getLoc(x,y) {
  var deferred = Q.defer();
  Q.ninvoke(request, 'get', {  // ... other options here
  }).spread(function(response, body) {
     deferred.resolve(body);
  });

  return deferred.promise;
}

您试图在异步回调被调用之前返回值,因此始终为undefined

或者,由于Q.ninvoke() 似乎返回了一个承诺,您可以这样做并避免常见的延迟反模式:

function getLoc(x,y) {
  return Q.ninvoke(request, 'get', {  // ... other options here
  }).spread(function(response, body) {
     return body;
  });
}

【讨论】:

  • 我希望您确实将其识别为反模式,并且已经在制定适当的解决方案......
  • 好吧,我判断你对 Promise 有点了解,而且它们基本上都是一样的 :-) Bluebird docs on spread?
  • @Bergi - 我添加了一个更好的方法。我不知道 Q 也不打算学习它,所以我只是先解决了明显的错误,但现在我看到 Q.ninvoke() 显然返回了一个承诺,因此可以返回。
  • @jfriend00 @Bergi 我意识到,在我将deferred.resolve(body); 移到里面之后,正如我在上面的问题中所说的那样,我收到的请求乱序返回,因为我还在我的i 值中传递了循环到我的getLoc(x,y,i) 中的 API GET 请求,我还在我的resolve() 中添加了i,但它返回了乱序的i 值。我需要它是连续的,我怎样才能做到这一点,同时还能返回我的body' value from my get request in myLoc()`?
  • @jazwu - 有许多不同的技术可以对异步操作进行排序或按原始顺序收集结果,即使在并行运行时也是如此。这似乎是一个不同的问题(我想我们现在已经回答了你原来的问题)。我建议您搜索排序承诺操作,因为已经写了很多东西。如果您卡在那里,我们需要查看更多循环代码以查看正在排序的内容,您可以发布一个包含该代码的新问题以及对新问题的更完整描述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 2021-09-22
  • 1970-01-01
相关资源
最近更新 更多