プロミスには状態があり、それらは保留中として開始し、次のように解決できます。
- 満たされたという意味は、計算が正常に完了したことです。
- 拒否は、計算が失敗したことを意味します。
Promiseを返す関数はスローしないでください。代わりに拒否を返します。promiseのreturn関数からスローすると、両方を使用する必要があります。} catch {
と、と aの.catch
。約束されたAPIを使用している人々は、約束がスローされることを期待していません。JSで非同期APIがどのように機能するかわからない場合は、まずこの回答を参照してください。
1. DOMロードまたは他の1回限りのイベント:
したがって、Promiseを作成することは、通常、いつ決着するかを指定することを意味します。つまり、データが利用可能(およびでアクセス可能)であることを示すために、履行フェーズまたは却下フェーズに移行する時点を指定します.then
。
をサポートする最新のpromise実装 Promise
ネイティブES6 ようなコンストラクターようになります。
function load() {
return new Promise(function(resolve, reject) {
window.onload = resolve;
});
}
次に、結果のプロミスを次のように使用します。
load().then(function() {
// Do things after onload
});
据え置きをサポートするライブラリー(ここでは、この例では$ qを使用しますが、後でjQueryも使用します):
function load() {
var d = $q.defer();
window.onload = function() { d.resolve(); };
return d.promise;
}
またはjQueryのようなAPIを使用して、1回発生するイベントにフックします。
function done() {
var d = $.Deferred();
$("#myObject").once("click",function() {
d.resolve();
});
return d.promise();
}
2.プレーンコールバック:
よくあるので、これらのAPIはかなり一般的です…コールバックはJSで一般的です。持つの一般的なケースで見てみましょうonSuccess
とonFail
。
function getUserData(userId, onLoad, onFail) { …
Promise
ネイティブES6 promiseのようなコンストラクターをサポートする最新のpromise実装では、次のようになります。
function getUserDataAsync(userId) {
return new Promise(function(resolve, reject) {
getUserData(userId, resolve, reject);
});
}
据え置きをサポートするライブラリー(ここでは、この例ではjQueryを使用しますが、上記の$ qも使用しています):
function getUserDataAsync(userId) {
var d = $.Deferred();
getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });
return d.promise();
}
jQueryは$.Deferred(fn)
フォームも提供します。これには、new Promise(fn)
次のように、フォームを非常に厳密にエミュレートする式を記述できるという利点があります。
function getUserDataAsync(userId) {
return $.Deferred(function(dfrd) {
getUserData(userId, dfrd.resolve, dfrd.reject);
}).promise();
}
注:ここでは、jQueryの遅延resolve
およびreject
メソッドが「分離可能」であるという事実を利用しています。すなわち。それらはjQuery.Deferred()のインスタンスにバインドされています。すべてのライブラリがこの機能を提供するわけではありません。
3.ノードスタイルコールバック( "nodeback"):
ノードスタイルのコールバック(ノードバック)には特定の形式があり、コールバックは常に最後の引数であり、その最初のパラメーターはエラーです。まず手動で1つを約束します。
getStuff("dataParam", function(err, data) { …
に:
function getStuffAsync(param) {
return new Promise(function(resolve, reject) {
getStuff(param, function(err, data) {
if (err !== null) reject(err);
else resolve(data);
});
});
}
deferredsを使用すると、次のことができます(この例ではQを使用しましょう。ただし、Qは新しい構文をサポートします)。
function getStuffAsync(param) {
var d = Q.defer();
getStuff(param, function(err, data) {
if (err !== null) d.reject(err);
else d.resolve(data);
});
return d.promise;
}
一般に、手作業であまり多くのことを約束しないでください。Nodeを念頭に置いて設計されたPromiseライブラリのほとんどと、Node 8+のネイティブPromiseには、ノードバックを約束する組み込みのメソッドがあります。例えば
var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // Native promises, node only
4.ノードスタイルのコールバックを含むライブラリ全体:
ここに黄金律はありません、あなたはそれらを一つずつ約束します。ただし、一部のpromise実装では、これを一括で行うことができます(Bluebirdなど)。ノードバックAPIをpromise APIに変換するのは次のように簡単です。
Promise.promisifyAll(API);
または、Nodeのネイティブpromiseを使用します。
const { promisify } = require('util');
const promiseAPI = Object.entries(API).map(([key, v]) => ({key, fn: promisify(v)}))
.reduce((o, p) => Object.assign(o, {[p.key]: p.fn}), {});
ノート:
- もちろん、
.then
ハンドラーにいるときは、物事を約束する必要はありません。.then
ハンドラーからpromiseを返すと、そのpromiseの値で解決または拒否されます。から投げる.then
ハンドラーも良い習慣であり、約束を拒否します-これは有名な約束投げ安全です。
- 実際には
onload
、addEventListener
ではなくを使用する必要がありますonX
。