2

Meteor アプリ (Meteor 1.2.1) で使用する WYSIWYG エディター用のアップロード プラグインを作成しています。Amazon S3 へのファイルのアップロードにはSlingshotを使用しています。私のプラグインは、ファイルがアップロードされると、アップロードされたファイルへのリンクをエディターに挿入します。これまでのところ派手なことは何もありません。

単一ファイルのアップロードの場合、これは問題ではありません。複数ファイルのアップロードの場合、事態はさらに難しくなります。私が望むのは、すべてのファイルがアップロードされた後、ファイル名と URL の配列になり、すべてのリンクを含む素敵な HTML リストを挿入することです (正確なファイル/リンクの順序は気にしません)。

Slingshot は非同期関数を使用してファイルをアップロードします。

uploader.send(document.getElementById('input').files[0], function (error, downloadUrl) {
  if (error) {
    // Log service detailed response.
    console.error('Error uploading', uploader.xhr.response);
    alert (error);
  } else {
    Meteor.users.update(Meteor.userId(), {$push: {"profile.files": downloadUrl}});
  }
});

コールバックでアップロードされたファイルの URL を返します。たとえば、アップロードされた 5 つのファイルから 5 つの URL を収集するには、同期機能のように動作する Slingshot の非同期「送信」機能が必要だと思います。

すべてがクライアント上で行われるため、Meteor.wrapAsync が機能しないことを正しく理解していることを願っています。javascript Promise を調べましたが、かなり圧倒されます。Meteor のコンテキスト内でそれを理解するのは難しくなります。Promise-thing は有望に見えますが、どのパッケージを使用すればよいかわかりません。

非同期関数への複数の(同一の)呼び出しを連続して実行する(クライアント側)に取り組み、結果を収集し、すべてのアップロードが完了した後にそれらを使用する方法を誰かが説明できますか?

感謝します、

Cspr

4

2 に答える 2

2

非同期ライブラリには、これを可能にするメソッドが呼び出されてmapSeriesいます。(おそらく)非同期関数を使用して配列を反復処理することができ、最終的な非同期タスクが完了すると、すべての結果の配列が返されます。

var files = [file1, file2, file3];

function iterator(file, callback) {
  uploader.send(file, function(err, downloadUrl) {
    if (err) callback(err);
    else callback(null, downloadUrl);
  });
}

function done(err, results) {
  // results is an array of URLs
}

async.mapSeries(files, iterator, done);

リクエストが処理される順序を気にしない場合は、通常のasync.map方法を使用してタスクを並行して実行できます。

于 2015-11-12T23:33:28.630 に答える
1

入力ファイルを繰り返し処理し、それらを非同期にアップロードし、各コールバックが終了したかどうかを確認することを妨げるものはありますか?

var inputs = document.getElementsByTagName('input');
var urls = [];

for (var i = 0; i < inputs.length; i++) {

  if (inputs[i].files == null) { continue; }

  uploader.send(inputs[i].files[0], function (error, downloadUrl) {

    if (error) {

      console.error('Error uploading', uploader.xhr.response);

    } else {

      urls.push(downloadUrl);

      if (urls.length > inputs.length - 1)
        allFilesUploaded();
    }
  });
}

function allFilesUploaded () {

  Meteor.users.update(Meteor.userId(), {$push: {"profile.files": urls}});
  console.log('All done!');

}
于 2015-11-12T23:22:02.663 に答える