简体   繁体   English

使用Q库时Node.js承诺不起作用

[英]Nodejs promise not working when using q library

I am trying to learn promises on my own. 我试图独自学习诺言。 This is the code I wrote - 这是我写的代码-

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 );

Now this is not printing the contents. 现在,这不是打印内容。 I just get C:\\node\\Ex_Files_UaR_Node\\first>node example3.js hi bye 我刚得到C:\\ node \\ Ex_Files_UaR_Node \\ first> node example3.js嗨,再见

I was expecting to get - hi 7 bye 我期待得到-嗨7再见

Please let me know if there is anything very much evident which I am missing. 请让我知道我是否缺少任何明显的东西。

EDIT: 编辑:

PS The below code resolves the promise - PS下面的代码实现了承诺-

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 );

However the basic idea behind adding setTimeOut in Q.fcall was to delay the execution of the promise. 但是,在Q.fcall中添加setTimeOut的基本思想是延迟Promise的执行。 Any idea how to do that ? 知道怎么做吗?

There you go 你去

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

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

ES6 Promises are simpler. ES6承诺更简单。 p is resolved only after 2 seconds. p仅在2秒后解析。 Till then, It is not resolved, neither rejected. 直到那时,它仍然没有解决,也没有被拒绝。 So then executes only after 2 seconds 因此,仅在2秒后执行

There is a problem with your 1st log statement. 您的第一个日志语句有问题。

I've modified your code to work properly. 我已修改您的代码以使其正常工作。

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 );

But this code will print 7 , bye and hi in respective order because, the following actions happens syncronously: 但是此代码将按各自的顺序打印7,bye和hi,因为以下动作是同时发生的:

  • Promise gets registered with the call to the function fcall() . 承诺会通过调用fcall()
  • The promise variable registers a handler using then() method. promise变量使用then()方法注册处理程序。
  • Your timeout function, which is aiming at logging 'bye', is registered. 旨在登录“再见”的超时功能已注册。

Now the following things happens asynchronously in the following order: 现在,以下事情以下列顺序异步发生:

  • Your registered promise callback, where you are registering a timeout function to print 'hi' and returning value 7, is called as callback from fcall() . 您注册的promise回调(您将在其中注册超时函数以打印“ hi”并返回值7)称为fcall()回调。
  • Now the setTimeout registers the function aiming to log 'hi' and returns value 7. 现在,setTimeout注册了旨在记录“ hi”的函数并返回值7。
  • Promise gets resolved with value 7 and it logs the value to console. Promise将使用值7进行解析,并将该值记录到控制台。
  • The timeout for 'bye' gets expired and logs it to the console. “再见”的超时时间已过期,并将其记录到控制台。
  • The timeout for 'hi' gets expired and logs it to the console. “ hi”的超时已过期并将其记录到控制台。

Hope it makes the flow clear. 希望它使流程清楚。

I could not reproduce the problem of not getting the 7 in the output (even though your code has several logical mistakes), as this snippet (without any of the corrections) does produce it: 我无法重现未在输出中得到7的问题(即使您的代码有几个逻辑错误),因为此代码段(不进行任何更正) 确实会产生它:

 // 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> 

There are however several issues: 但是,有几个问题:

  • The first argument to the first setTimeout is not a function: you pass it console.log('hi') instead of function(){console.log('hi');} . 第一个setTimeout的第一个参数不是函数:您将其传递给console.log('hi')而不是function(){console.log('hi');}
  • return 7 will be executed immediately. return 7将立即执行。 If you want a delay for the initial promise to settle, then Q.fcall is not the method you need: you need Q.Promise instead. 如果您希望延迟初始承诺的履行,则Q.fcall不是您需要的方法:您需要Q.Promise

Here is how your intended behaviour would be coded then: 以下是您的预期行为的编码方式:

 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> 

Note that Node has a native Promise library with which you can do the same. 请注意,Node具有本机的Promise库,您可以使用该库执行相同的操作。 There is really no need to include Q. Just replace Q.Promise(...) with new 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 ); 

Note that there is a slight difference in the output order for the "7". 请注意,“ 7”的输出顺序略有不同。 This is because the native implementation of Promises uses a microtask to schedule the execution of the then callback, while Q uses an event on the main queue to schedule that execution, which comes later. 这是因为Promises的本机实现使用微任务来调度then回调的执行,而Q使用主队列上的事件来调度该执行,稍后再执行。 Many will consider the native behaviour "more correct". 许多人会认为本地行为“更正确”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM