2016-05-03 9 views
1

私はNode.jsとBluebird約束ライブラリを使用しています。このコードは正確にように動作しますこれらの機能をどのように約束できますか?

は私がしたい:

/* 
* Try using Bluebird promisify(): 
* - "Good" case: this works perfectly. 
* ... but it DOESN'T use "promisify()"; it creates a new promise for each function. 
* - SAMPLE OUTPUT: 
*  callABC()... 
*  a(): [ 'a' ] 
*  b(): [ 'a', 'b' ] 
*  c(): [ 'a', 'b', 'c' ] 
*  Done: results: [ 'a', 'b', 'c' ] 
*/ 
var Promise = require('bluebird'); 

var a = function (results) { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     results.push("a"); 
     console.log("a(): ", results); 
     resolve(results); 
    }, 15); 
    }); 
} 

var b = function (results) { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     results.push("b"); 
     console.log("b(): ", results); 
     resolve(results); 
    }, 5); 
    }); 
} 

var c = function (results) { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     results.push("c"); 
     console.log("c(): ", results); 
     resolve(results); 
    }, 10); 
    }); 
} 


var callABC = function (results) { 
    console.log("callABC()..."); 
    a(results) 
    .then(b) 
    .then(c) 
    .then(function (results) { 
    console.log("Done: results:", results); 
    }) 
    .catch(function (err) { 
    console.log("Error:", err); 
    }); 
} 

callABC([]); 

は私が手動で次のように独自の約束をインスタンス化することは "悪い" と考えることができることを理解する:

Q:上記のスニペットをどのように「約束する」ことができますか?

私は多くのことを試しました。彼らのどれも働いていない。例:

/* 
* Try using Bluebird promisify(): 
* - Fails: never calls b() or c() 
*/ 
var Promise = require('bluebird'); 

var a = Promise.promisify(function (results) { 
    setTimeout(function() { 
    results.push("a"); 
    console.log("a(): ", results); 
    }, 15); 
}); 

var b = Promise.promisify(function (results) { 
    setTimeout(function() { 
    results.push("b"); 
    console.log("b(): ", results); 
    }, 5); 
}); 

var c = Promise.promisify(function (results) { 
    setTimeout(function() { 
    results.push("c"); 
    console.log("c(): ", results); 
    }, 10); 
}); 

var callABC = function (results) { 
    console.log("callABC()..."); 
    a(results) 
    .then(b) 
    .then(c) 
    .then(function (results) { 
    console.log("Done: results:", results); 
    }) 
    .catch(function (err) { 
    console.log("Error:", err); 
    }); 
} 

callABC([]); 

Q:最初の例を「約束する」正しい方法はありますか?

Q:具体的には、どうすればよい「解決()」または「拒否()」私のコールバック私は手動new Promise()ための自動化Promise.promisify()またはPromise.promisifyAll()を置き換える場合は?私は "スロー"が.catch()を呼び出すと想像しますが、別の(より良い?)メカニズムがありますか?

Q:制限はありますか?例えば、関数はコールバックパラメータを "promisified"にする必要がありますか?

+2

'promisify'は魔法をしません。コールバックを受け取る関数に対してのみ機能します。良いユースケースについては、[既存のコールバックAPIを約束に変換するにはどうすればいいですか?](http://stackoverflow.com/q/22519784/1048572)を参照してください。 – Bergi

+1

この問題を解決する正しい方法は、 'promise.delay'を使うことです。これは' setTimeout'の有名なバージョンです。それを試してみてください。 – Bergi

+0

@Bergi:1)これは私が "promisifyは魔法をしません"という答えです。コールバックを取る関数でのみ機能します。 2)リンクをありがとう。 3) "setTimeout()"はテストのためのものです。それは実際の質問とは何の関係もありません。 4)あなたのコメントを「回答」に入れたいのであれば、私はそれを「受け入れる」ことができます。 – paulsm4

答えて

0

答えは「すべてのJS機能を約束することはできません」です。具体的に:

http://bluebirdjs.com/docs/api/promise.promisify.html

Promise.promisify)...は、与えられた nodeFunctionをラップする関数を返します。コールバックを取る代わりに、返された関数は、与えられたノード関数 のコールバックの振る舞いによって運命が決定された約束を返します。 ノード関数は、最後の引数としてコールバックを受け入れ、 コールバックをエラーの第1引数として呼び出し、 第2引数のコールバックを呼び出すnode.js 規約に準拠する必要があります。

上記の例では、「promise.promisify()」は正しく機能しません。

関連する問題