1

node-gcloud https://github.com/GoogleCloudPlatform/gcloud-nodeを使用して Google Cloud Storage とやり取りしています。

クライアントに小さな API セットを提供するために、node.js サーバー (私の最初の node.js プロジェクト) を開発しています。基本的に、ユーザーがファイルをアップロードすると、API 呼び出しは署名された URL を返し、そのファイルを表示します。

getSignedUrl 関数は非同期https://googlecloudplatform.github.io/gcloud-node/#/docs/v0.8.1/storage?method=getSignedUrlであり、別の関数からその結果を返す方法が見つかりません。

Bluebird のプロミスで遊び始めましたが、その要点に到達できません。これが私のコードです:

var _signedUrl = function(bucket,url,options) {
  new Promise(function (resolve, reject) {
    var signed_url
    bucket.getSignedUrl(options, function(err, url) {
      signed_url = err || url;
      console.log("This is defined: " + signed_url)

      return signed_url   
    })
  })
}


var _getSignedUrl = function(url) {
  new Promise(function(resolve) {
    var   options = config.gs
      ,   expires = Math.round(Date.now() / 1000) + (60 * 60 * 24 * 14)
      ,   bucket  = project.storage.bucket({bucketName: config.gs.bucket, credentials: config.gs })
      ,   signed_url = null

    options.action  = 'read'
    options.expires =  expires// 2 weeks.
    options.resource= url
    signed_url = resolve(_signedUrl(bucket,url,options))

    console.log("This is undefined: " + signed_url)

    return JSON.stringify( {url: signed_url, expires: expires} );

  });
}

どのように機能するかの基本が欠けていると思うので、ヒントをいただければ幸いです。

編集:

最初のコメントと同様に、ソリューションを作り直しました。

getSignedUrl: function() {
    var   options = config.gs
      ,   expires = Math.round(Date.now() / 1000) + (60 * 60 * 24 * 14)
      ,   bucket  = project.storage.bucket({bucketName: config.gs.bucket, credentials: config.gs })
      ,   signed_url = null

    options.action  = 'read'
    options.expires =  expires// 2 weeks.
    options.resource= this.url

    Promise.promisifyAll(bucket);

    return bucket.getSignedUrlAsync(options).catch(function(err) {
        return url; // ignore errors and use the url instead
    }).then(function(signed_url) {
        return JSON.stringify( {url: signed_url, expires: expires} );
    });
}

ダブルリターンがどのように機能するのかははっきりしていませんが、リターンバケットを保持している場合

私が得るのはこの出力です:

{ url: { _bitField: 0、_fulfillmentHandler0: 未定義、_rejectionHandler0: 未定義、_promise0: 未定義、_receiver0: 未定義、_settledValue: 未定義、_boundTo: 未定義} }

、およびそれを削除して保持する場合

return JSON.stringify( {url: signed_url, expires: expires} );

以前と同じように未定義になります。私は何が欠けていますか?

4

1 に答える 1

2

いくつかのポイント:

  • new Promise(function(res, rej){ … })リゾルバー コールバック内では、実際にはor (非同期的に)を呼び出す 必要がありますが、何も呼び出す必要はありません。resolve()reject()return
  • resolve何も返しません。promise の結果を返す「待機」操作のように使用しているように見えましたが、そのようなことは不可能です。promise はまだ非同期です。
  • 実際には、電話をかける必要はまったくありませんnew Promise代わりに約束を使用してください。

あなたのコードはむしろ次のようになります

var gcloud = require('gcloud');
Promise.promisifyAll(gcloud); // if that doesn't work, call it once on a
                              // specific bucket instead

function getSignedUrl(url) {
    var options = config.gs,
        expires = Math.round(Date.now() / 1000) + (60 * 60 * 24 * 14),
        bucket  = project.storage.bucket({bucketName: config.gs.bucket, credentials: config.gs });

    options.action  = 'read';
    options.expires =  expires; // 2 weeks.
    options.resource = url;
    return bucket.getSignedUrlAsync(options).catch(function(err) {
        return url; // ignore errors and use the url instead
    }).then(function(signed_url) {
        console.log("This is now defined: " + signed_url);
        return JSON.stringify( {url: signed_url, expires: expires} );
    });
}
于 2014-10-14T12:51:53.443 に答える