Overviews
非同期処理の結果を渡すもので、コールバックの代わりになる。
コールバックは、処理の手順を書いた他のfunction
Benefits
結果を成功時と失敗時に分けてかける。
sample.js
function asyncFunc() {
return new Promise(
function (resolve, reject) {
...
resolve(result);
...
reject(error);
})
}
asyncFunc()
.then(result => { ... })
.catch(error => { ... })
非同期処理を行うためのパターン
ひとつだけ結果を返す(コールバック)
Promiseはコールバックを返すのに効率的
非同期処理がPromiseを返す:最終結果を含む
コールバックがPromiseを通して行われて結果がでる
valueとevent発行、両方のコンテナ
callbackの代わりにPromiseを使う利点
- 逆戻りしない rejectとresolveの値を持っているから、コントロールができる
- 変化がシンプル 最初にasyncを使ったPromiseでデータを取得、 その後にそのデータを使った処理(loops, mapping)を使うと便利
- エラー処理に便利 "try-catch"などかかなくてよい
Callbacks
sample2.js
fs.readFile('config.json',
function (error, text) {
if (error) {
console.error('Error while reading config file');
} else {
try {
const obj = JSON.parse(text);
console.log(JSON.stringify(obj, null, 4));
} catch (e) {
console.error('Invalid JSON in file');
}
}
});
Promises
sample4.js
fs.readFile('config.json')
.then( text => {
const obj = JSON.parse(text);
console.log(JSON.stringify(obj, null, 4));
})
.catch( error => {
console.error('Invalid JSON in file');
})
Promisesの作り方
sample5.js
const p = new Promise(
function (resolve, reject) {
...
if ( ... ) {
resolve(value); // 成功条件と渡す値を定義
} else {
reject (reason); // 失敗条件と渡す値を定義
}
});
Promisesのstates
状態は3種類
Pending: 結果がまだ出ていない状態(初期状態)
Fulfilled: 結果がでて成功!
Rejected: 処理中にエラーが起きて失敗
エラーの状態のみ明したい場合は
promise.then(
null,
error => { /* rejection */ });
promise.catch(error => { /* rejection */ })
Example
// Example1
function readFile(filename) {
return new Promise(
function (resolve, reject) {
readFile(filename, { encoding: 'utf8' },
(error, data) => {
if (error) {
reject(error)
} else {
resolve(data)
}
})
})
}
readFile(process.argv[2])
.then(text => {
resolve(text)
})
.catch(error => {
console.log(error)
})
// Example2: delaying an activity
resolve(PARAMETER)とするかresolveとするかは自由。
parameterがある場合はresolve(PARAMETER)と書く。
function delay(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms); // 成功した場合はms秒後にsetTimeoutを発行させる。
}
}
delay(5000).then(() => { // 成功時に返す値がないからparameterは無視してOK
console.log('5 seconds has passed!')
})
// Example3: timing out a Promise
function timeout(ms, promise) {
return new Promise((reslve, reject) => {
promise.then(resolve);
setTimeout(() => {
reject(new Error('Timeout after' + ms + 'ms'));
}, ms);
})
}
timeout(5000, httpGet('http://example.com/file.txt'))
.then((value) => {
console.log('Contents: ' + value);
})
.catch((reason) => {
console.log('Error or timeout', reason)
})
// Promisesを作る他の方法
Promise.resolve('abc')
.then(x => console.log(x));
const p = new Promise(() => null);
console.log(Promise.resolve(p) === p);