1

メールのリストをループして、それらが有効であることを確認する必要があります。検証に失敗した場合は、エラーをスローしてMochaに通知します。

it('validates valid email addresses', function (done) {
  [
    'oliverash@me.com',
    'oliver.ash@me.com',
    'oliver-ash@me.com',
    'oliver+ash@me.com',
    'oliver\'s-email@me.com'
  ].forEach(function (value) {
    user.email = value

    user.validate(function (err) {
      // Failed to validate, throw an error
      if (err) {
        throw new Error()
      }
    })
  })

  // All documents validated, so call `done`
  done()
})

ただし、このコードは正しく機能していないようです。無効な場合は、配列の最後の電子メールのみが無効になります。

私は何が間違っているのですか?

4

2 に答える 2

3

非同期ユーティリティライブラリを使用して、非同期ループの実行を簡素化できます。

it('validates valid email addresses', function (done) {
  async.forEach([
    'oliverash@me.com',
    'oliver.ash@me.com',
    'oliver-ash@me.com',
    'oliver+ash@me.com',
    'oliver\'s-email@me.com'
  ], 
  function (value, callback) {
    user.email = value
    user.validate(callback)
  },
  function (err) {
    if (err) {
      throw new Error()
    }
    done()
  })
})

最初の関数は配列内の各要素で呼び出され、配列からのアイテムとコールバック関数の2つの引数を取ります。コールバックがエラーを受信すると、すぐに反復を停止します。配列内のすべての項目が完了すると(またはそれらのいずれかがエラーを返すと)、final関数が呼び出されます。この例では、エラーをスローするか、Mochadone関数を実行します。

asyncのreadmeには、forEach関数がどのように機能するかについての適切な説明があります。

于 2013-02-02T14:41:16.960 に答える
1

関数が非同期の場合user.validate、forEach呼び出しはのコールバック呼び出しを待機しませんuser.validate

つまり、forEach関数はuser.validateすべてのコールバックを呼び出すdone()前に終了し、すべての検証が終了する前に呼び出します。

forEach関数のすべてのパラメーターを使用done()して、user.validateコールバックを呼び出す必要があります。呼び出されたコールバックをカウントするために1つのカウント変数を追加し、関数を呼び出す必要があるときを認識しますdone()

it('validates valid email addresses', function (done) {
  var count = 0;     // count variable
  [
    'oliverash@me.com',
    'oliver.ash@me.com',
    'oliver-ash@me.com',
    'oliver+ash@me.com',
    'oliver\'s-email@me.com'
  ].forEach(function (value, index, array) {
    user.email = value;

    user.validate(function (err) {
      ++count;      // Callback called, we add +1 to count.
      if (err) {
        throw new Error();
      }
      // Check if all callbacks have been called and call done if true.
      if (count === array.length)
        done();
    });

  });

})

これはうまくいくはずです。私はそれをテストしませんでしたが、それは動作するはずです。

PS:セミコロンを忘れないでください。場合によっては未定義の動作を引き起こす可能性があり、それらを配置しないのは悪い習慣です(私たちはプログラマーです!)。

編集-08/06/13:Javascriptでセミコロンについて何かを読んで、このスレッドについて覚えておいてください。これが、コードにセミコロンを入れる必要がある理由です:http: //bonsaiden.github.io/JavaScript-Garden/#core.semicolon

于 2013-02-02T14:35:17.230 に答える