Nodejs承诺在使用q库时不起作用

时间:2017-05-23 11:08:48

标签: javascript node.js q

我正在努力学习自己的承诺。这是我写的代码 -

var Q = require('q');

var promise = Q.fcall(function() {
  // I expect this time out to delay returning the response 7.
  setTimeout( console.log('hi'), 1000 );
  return 7;
});

promise.then(function(contents) {
  console.log(contents);
});
// Added this timeout so that the javascript execution context(node ex.js) remains alive before the code in the then block is resolved.
setTimeout( function(){console.log('bye');}, 1000 );

现在这不是打印内容。我得到了 C:\ node \ Ex_Files_UaR_Node \ first> node example3.js 嗨 再见

我原以为 - 嗨 7 再见

如果有任何我非常遗憾的事情,请告诉我。

编辑:

P.S以下代码解决了承诺 -

var Q = require('q');

var promise = Q.fcall(function() {
  setTimeout( function(){console.log('hi');}, 1000 );
  return 7;
});

promise.then(function(contents) {
  console.log(contents);
});

setTimeout( function(){console.log('bye');}, 1000 );

然而,在Q.fcall中添加setTimeOut背后的基本思想是延迟执行promise。知道怎么做吗?

3 个答案:

答案 0 :(得分:0)

你去了

let p = new Promise((resolve, reject) => {  
   setTimeout(() => resolve(4), 2000);
});

p.then((res) => {  
  console.log(res);
});

ES6承诺更简单。 p仅在2秒后解析。直到那时,它没有得到解决,也没有被拒绝。所以然后只在2秒后执行

答案 1 :(得分:0)

您的第一个日志声明存在问题。

我已修改您的代码以使其正常工作。

var Q=require('q');
var promise = Q.fcall(function() {
    setTimeout( function(){console.log('hi')}, 1000 );
    return 7;
})
promise.then(function(contents) {
    console.log(contents);
});

setTimeout(function(){console.log('bye');}, 1000 );

但是这段代码将按相应的顺序打印7,bye和hi,因为以下操作同步发生:

  • Promise通过调用函数fcall()注册。
  • promise变量使用then()方法注册处理程序。
  • 您的超时功能,即以“再见”为目标,已注册。

现在,以下事项按以下顺序异步发生:

  • 您注册的承诺回拨,您注册超时 函数打印'hi'并返回值7,称为回调 来自fcall()
  • 现在setTimeout注册了用于记录'hi'和。的函数 返回值7。
  • Promise以值7解析,并将值记录到控制台。
  • 'bye'的超时时间已过期,并将其记录到控制台。
  • 'hi'的超时时间已过期,并将其记录到控制台。

希望它能说清楚。

答案 2 :(得分:0)

我无法重现输出中没有得到7的问题(即使你的代码有几个逻辑错误),因为这个代码片段(没有任何修正) 生成它:< / p>

// This is browser version, so `require` is replaced by `script src` tag.
//var Q = require('q');

var promise = Q.fcall(function() {
  // I expect this time out to delay returning the response 7.
  setTimeout( console.log('hi'), 1000 );
  return 7;
});

promise.then(function(contents) {
  console.log(contents);
});
// Added this timeout so that the javascript execution context(node ex.js) remains alive before the code in the then block is resolved.
setTimeout( function(){console.log('bye');}, 1000 );
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.5.0/q.js"></script>

但有几个问题:

  • 第一个setTimeout的第一个参数不是函数:您传递console.log('hi')而不是function(){console.log('hi');}
  • return 7将立即执行。如果您希望延迟初始承诺,那么Q.fcall不是您需要的方法:您需要Q.Promise

以下是您的预期行为的编码方式:

var promise = Q.Promise(function (resolve, reject) {
    setTimeout( function () {
        console.log('hi');
        resolve(7);
    }, 1000 );
});

promise.then(function(contents) {
  console.log(contents);
});

setTimeout( function(){console.log('bye');}, 1000 );
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.5.0/q.js"></script>

请注意,Node有一个本机Promise库,您可以使用它来执行相同的操作。实际上不需要包含Q.只需将Q.Promise(...)替换为new Promise(...)

var promise = new Promise(function (resolve, reject) {
    setTimeout( function () {
        console.log('hi');
        resolve(7);
    }, 1000 );
});

promise.then(function(contents) {
  console.log(contents);
});

setTimeout( function(){console.log('bye');}, 1000 );

请注意,“7”的输出顺序略有不同。这是因为Promises的本机实现使用微任务来安排then回调的执行,而Q使用主队列上的事件来安排执行,这将在稍后进行。许多人会认为原生行为“更正确”。