LoginSignup
0
0

More than 5 years have passed since last update.

Promises

Posted at

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を使う利点

  1. 逆戻りしない rejectとresolveの値を持っているから、コントロールができる
  2. 変化がシンプル 最初にasyncを使ったPromiseでデータを取得、 その後にそのデータを使った処理(loops, mapping)を使うと便利
  3. エラー処理に便利 "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);

Referece

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0