2

Meteor 1.* と Iron Router 1.* を使用しています。

Meteor のサーバー側、Meteor メソッドの外側、特にサーバー側の Iron Router ルート内で Node.js 呼び出しを使用しています。

これまでのところ、ルート内のコードの一部は次のようになります。

  fs.mkdir(filebox, function (e) {
    if(!e || e.code === 'EEXIST') {
      fs.writeFile(file1, function (err) {
        if (err) throw err;

        fs.writeFile(file2, function (err) {
          if (err) throw err;

          fs.writeFile(file.3, function (err) {
            if (err) throw err;

            ExternalLibrary.do_something_(file1, function (err, buffer) {
              if (err) throw err;

              ExternalLibrary.do_something_(file2, function (err, buffer) {
                if (err) throw err;

                ExternalLibrary.do_something_(file3, function (err, buffer) {
                  if (err) throw err;

                  some_object = { first: file1, second: file2 }

                  ExternalLibrary.do_something_else_(some_object, function (err, buffer) {
                    if (err) throw err;

                    fs.readFile(file1, function (err, data) {
                      if (err) throw err;

                      res.write(data);
                      res.end();
                    });
                  });
                });
              });
            });
          });
        });
      });
    } else {
      console.log(e);
    }
  });

私の問題は、 fs.write と ExternalLibrary への呼び出しをさらに追加し、さらにこれらの呼び出しを条件付きにする必要があることです。

コールバック地獄に突入しそうです。

コールバックについて

Meteor がコルーチン (またはファイバー、または継続) を使用していることは知っていますが、これがどのように機能するかについては何も知りません。Meteor メソッド内では、Meteor.wrapAsync を使用するオプションがあります。

Node.js Promises and Generators についていくつか読んだことがあります。具体的には、frozeman/q-meteor ライブラリを試しています。

質問

このツリーを「平坦化」してコールバック地獄から自分を救う最善の方法は何ですか? 条件付きメソッド呼び出しも可能にするソリューションが必要です。たとえば、最終的には、上記のコード例に次のようなものを追加する必要があります。

if (some_condition === true) {
  // call this method or node function
  fs.writeFile(file4, function (err) {
    fs.writeFile(file5, function (err) {
      // do something
    }
  }
}
else {
  // call this method or node function
  fs.writeFile(file6, function (err) {
    fs.writeFile(file7, function (err) {
      // do something
    }
  }
}
4

1 に答える 1

0

私は最終的にソリューションに Promises を使用しました。Kris kriskowal/q による優れた Q ライブラリを使用しました。具体的には、この Meteor ラッパーはfrozeman/q-meteor です。

コードは次のとおりです。

makeDirectory(filebox)
  .then(function () {
    console.log('in write file function');
    return writeFile(file1, data);
  })
  .then(function () {
    console.log('in write file function');
    return writeFile(file2, data);
  })
  .then(function () {
    console.log('in write file function');
    return writeFile(file3, data);
  })
  .then(function () {
    console.log('in external lib function');
    return ExternalLibrary._do_something(file1, data1, output1);
  })
  .then(function () {
    console.log('in external lib function');
    return ExternalLibrary._do_something(file2, data2, output2);
  })
  .then(function () {
    console.log('in external lib function');
    return ExternalLibrary._do_something(file3, data3, output3);
  })
  .then(function () {
    console.log('in concat function');
    return ExternalLibrary.cat(fileToCat, outputCat);
  })
  .then(function () {
    console.log('in read file function');
    return readFile(outputCat);
  })
  .then(function (result) {
    console.log('in the response function');
    res.write(result);
    res.end();
  })
  .catch(function (error) {
    console.log('darn error: ', error);
  })
  .done(function (result) {
    console.log('done');
  });

それぞれの .then 内の外部ライブラリと関数呼び出しの両方が遅延 promise を返し、その出力は先行する .then 関数呼び出しで使用できます。

始めるのに役立ついくつかのリンク:

于 2015-03-09T19:57:13.077 に答える