2017-05-23 10 views
0

私は自分で約束を勉強しようとしています。これは私が書いたコードです -qライブラリを使用しているときにNodejsが動作しないことを約束します。

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を取得:私は得るために期待していた\ノード\ Ex_Files_UaR_Node \最初>ノードexample3.js ハイテク さようなら

- ハイテクさようなら

は何がある場合は私に知らせてください非常に私が欠けていることははっきりと分かる。

EDIT:以下のコードは約束を解決

P.S - Q.fcallでのsetTimeoutを追加することの背後にある基本的な考え方は、約束の実行を遅らせることだったしかし

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

。どのようにそれを行うにはどのようなアイデア?そこ

+0

これは非常に多くのレベルで間違っています。あなたは 'setTimeout'を実行することを正確に期待しましたか? – Bergi

+0

私は、プロミスが解決されるまでに少し時間がかかるように、いくつかの遅延を追加するためにsetTimeOutを追加しました。しかし、それが解決されていないので、約束が解決される前に執行自体が終わったと思っています。それで、私は最後に2回目のタイムアウトを追加したので、解決する約束の時間を購入しました。 – user3276247

+0

それで、どのログの間に1秒待つと予想されますか? – Bergi

答えて

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

しかし、次のアクションが起こるsyncronously、ので、このコードは、それぞれ順番にハイと別れ、7を印刷します:

  • の約束は、関数fcall()への呼び出しで登録されます。
  • 約束変数は、then()メソッドを使用してハンドラを登録します。
  • 「bye」のログ記録を目的としたタイムアウト機能が登録されています。

今、次のものが次の順序で非同期的に起こる:あなたは「ハイ」印刷するには、タイムアウト 機能を登録し、値7を返している

  • ご登録約束コールバックは、コールバックとして呼ばれています からfcall()
  • setTimeoutは 'hi'を記録する機能を登録し、 は値7を返します。
  • プロミスは値7で解決され、コンソールに値を記録します。
  • 'bye'のタイムアウトが切れてコンソールに記録されます。
  • 'hi'のタイムアウトが切れ、コンソールにログアウトします。

フローを明確にしたいと考えています。

+0

実際にsetTimeOutを追加するという基本的な意図は、約束を直ちに7に戻すのを遅らせることでした。どのようにそれを行うにはどのようなアイデア? – user3276247

+0

私はpromiseの実行を遅らせる方法を見つけました - var Q = require( 'q'); var deferred = Q.defer(); setTimeout(function(){(ハイ)}; deferred.resolve(9);}); return deferred.promise; } ; promise.then(function(contents){ console.log(contents); }); setTimeout(function(){console.log( 'bye');}、1000); – user3276247

+0

これは最初の質問ではありませんでしたので、私はあなたの答えを受け入れます。 – user3276247

0

あなたは

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

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

ES6の約束は簡単です行きます。 pは2秒後に解決されます。それまでは、解決されておらず、どちらも拒否されていません。したがって、2秒後に実行されます

+0

ya。 Promiseはすぐ上に解決します。実際には私は約束の非同期性をテストできるようにいくつかの遅延を加えたいと思っていました。どのようにしてそれを行うことができますか? – user3276247

+0

Qを使って行う必要がありますか? –

+0

である必要はありません。しかし、私は角度のjsベースのアプリケーションで前に$ qを使用していました。それが私がこのようにした理由です。 – user3276247

0

私はがそれを生み出すん(修正のいずれかなし)このスニペットとして、(あなたのコードは、いくつかの論理的なミスを持っているにもかかわらず)の出力に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>

  • 最初にargU:

    は、しかし、いくつかの問題があります最初のsetTimeoutへの入力は関数ではありません:function(){console.log('hi');}の代わりに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>

注意ノードはあなたが同じことを行うことが可能なネイティブの約束のライブラリを持っていること。ただ、new Promise(...)Q.Promise(...)を置き換えるQ.を含める必要は本当にありません:

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」の出力順に若干の差があること。これは、プロミスのネイティブ実装では、マイクロタスクを使用してthenコールバックの実行をスケジュールするのに対して、Qはメインキューのイベントを使用してその実行をスケジュールするためです。多くの人がネイティブの振る舞いを「より正確」と考えます。

関連する問題