【问题标题】:.then() function is called before main function gets completed - Q.nfcall.then() 函数在主函数完成之前被调用 - Q.nfcall
【发布时间】:2019-01-10 03:23:22
【问题描述】:

A() 函数在1000 ms 之后返回承诺并抛出错误。所以,下一次执行应该进入catch。但是,.then() 函数即使在 main 函数抛出错误后也会执行。

Test.js

var Test1 = require("./Test1.js")
var Q = require('q');
var value = "Hardik";
var value1 = "Shah";

A()
  .then(Test1.B(value, value1))
  .catch(function(e){
    console.log("In catch: ", e.message);
  });


  function A(){
    console.log("In A function");
    return Q.nfcall(AInner);
  }

  function AInner(callback){
    setTimeout(function() {
      callback({message: "Error from A Inner"});
    }, 1000)
  }

Test1.js

'use strict';

var Q = require("q");

module.exports = {B:B}

function B(value, value1){
  console.log("In B function: ", value, " ", value1);
  return Q.nfcall(BInner);
}

function BInner(callback){
  console.log("In BInner function");
  callback({message: "Error from BInner"});
}

实际输出:

In A function
In B function:  Hardik   Shah
In BInner function
In catch: Error from A Inner

预期输出:

In A function
Error from A Inner // After 1000 ms

我通过修改以下代码解决了问题:完美运行

A()
  .then(function(){
    return Test1.B(value, value1)
  }).then(function(data){
     console.log("final data", data);
  })
  .catch(function(e){
    console.log(e.message);
  });

但是,上面的代码有什么问题?

请给我一个很好的解释,正确的方法是按照then而不是then的顺序编写代码。

您可以在这里尝试https://repl.it/@hrdk108/Hardik-Shah-Issue1 重现问题。

【问题讨论】:

  • 因为AInner 没有返回一个promise?,它返回了undefined,链接受一个有效值来继续链。我可能错了。
  • @kiddorails AInner 返回callback function,我已经处理了返回的callback function 以使用Q.nfcall 转换为promise。这不是问题,因为如果是这样,它将在未完成执行的情况下引发错误。
  • 想通了。更改为.then(() => Test1.B(value, value1)),您正在调用Test1.B,而不是提供回调。
  • 按照 then 的顺序而不是 then 的顺序编写代码。”是什么意思?
  • @Bergi 我的意思是我想编写类似A.then(B).then(C).catch(function(e){}) 的代码,其中A,B and C 是函数。

标签: node.js promise q


【解决方案1】:

问题是,您在 then 内调用 Test1.B(value, value1),而不是将其保留为回调。因为,一旦你将它用作调用,它就会启动它自己的承诺链。要修复它,请将其更改为:

var Test1 = require("./Test1.js")
var Q = require('q');
var value = "Hardik";
var value1 = "Shah";

A()
  .then(function() { Test1.B(value, value1) }) // note here
  .catch(function(e){
    console.log("In catch: ", e.message);
  });


  function A(){
    console.log("In A function");
    return Q.nfcall(AInner);
  }

  function AInner(callback){
    setTimeout(function() {
      callback({message: "Error from A Inner"});
    }, 1000)
  }

【讨论】:

  • 这个解决方案我已经在I have solved issue by modifying below code: Works perfect部分下的问题中提到了。
  • 啊。我没有看到那个部分。但底线是,您确实意识到为什么您的第一个版本现在不起作用,对吗?您必须将要调用的函数提供给then,而不是调用它
【解决方案2】:

经过长时间的头脑风暴,我想通了,这只是一个愚蠢的错误。

  • 那个错误只是因为我在定义时调用了Test1.B() 进入then。上面的答案已经回答了。所以,我在问题中已经提到了一种解决方案。


第二种解决方案:


编写then序列的正确方法是:

Test1.B 没有参数的函数:


A()
  .then(Test1.B)
  .catch(function(e){
    console.log("In catch: ", e.message);
  });

Test1.B 带参数: 使用 bind

A()
  .then(Test1.B.bind(null, value, value1))
  .catch(function(e){
    console.log("In catch: ", e.message);
  });

在此处查看更正示例https://repl.it/@hrdk108/Hardik-Shah-Issue1


仅供参考,

实际上,当您使用Q.nfcall 时,您应该注意传递参数的设计。

  • nfcall 需要单独提供参数

例如:

Q.nfcall(B, value, value1);

【讨论】:

    猜你喜欢
    • 2016-05-13
    • 2019-02-22
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2018-04-05
    • 1970-01-01
    相关资源
    最近更新 更多