2016-11-07 10 views
1

私はfetchMerchantDataと呼ばれるメソッドを持っています。これは3つの他の非同期メソッドを呼び出します。 Promiseを使用して、すべての要求が完了するまでresp.direct(301, ...)を呼び出さないようにしようとしていますが、動作していません。ノード+ ES6:非同期リクエストでPromise.allを使用するには?

function saveMerchant(merchant_id, access_token, locations) { 
    const merchantRef = database.ref('merchants').child(merchant_id); 
    const location_ids = locations.map(location => location.id); 

    merchantRef.update({ 
    access_token, 
    location_ids, 
    }); 
} 

がどのように私はこれを同期します:

function fetchOauth2Token(authorizationCode, resp) { 
    ... 
    request({ 
    url: `https://connect.squareup.com/oauth2/token`, 
    method: "POST", 
    json: true, 
    headers: oauthRequestHeaders, 
    form: oauthRequestBody, 
    }, (error, oauthResp, body) => { 
    if (body.access_token) { 
     Promise.resolve(fetchMerchantData(body.access_token, body.merchant_id)).then(() => { 
     console.log("last!"); //<--------------------- this is printing first 
     resp.redirect(
      301, 
      `myurl.com/blah` 
     ); 
     }); 
     ; 
    } else { 
     // TODO find out what to do on failure 
     resp.redirect(301, `myurl.com/?error=true`); 
    } 
    }) 
} 

function fetchMerchantData(access_token, merchant_id){ 
    const updates = {}; 
    request({ 
    url: `https://connect.squareup.com/v1/me/locations`, 
    method: "GET", 
    json: true, 
    headers: { 
     Authorization: `Bearer ${access_token}`, 
     Accept: 'application/json', 
     "Content-Type": "application/json", 
    }, 
    }, (error, response) => { 
    if (!error) { 
     const locations = response.body; 

     Promise.all([ 
     saveMerchant(merchant_id, access_token, locations), 
     saveLocations(merchant_id, locations), 
     installWebhookForLocations(access_token, locations), 
     ]).then(values => { 
     console.log("first!"); //<--------------------- this is printing last 
     return Promise.resolve("Success"); 
     }) 
    } 
    }); 
} 

そして、ここではfirebase呼び出すsaveMerchant方法の一例ですか?

== UPDATE ==

これは私のinstallWebhookForLocations方法がどのように見えるかです:ここでは

function installWebhookForLocations(access_token, locations){ 
    const locationIds = locations.map(location => location.id); 
    locationIds.forEach((locationId) => { 
    request({ 
     url: `https://connect.squareup.com/v1/${locationId}/webhooks`, 
     method: "PUT", 
     json: true, 
     headers: { 
     Authorization: `Bearer ${access_token}`, 
     Accept: 'application/json', 
     "Content-Type": "application/json", 
     }, 
     body: ["PAYMENT_UPDATED"], 
    }, (error) => { 
     if (!error){ 
     console.log(`Webhook installed for ${locationId}`); 
     } 
    }); 
    }); 
} 
+1

'saveMerchant'は何も返しませんか? –

+0

いいえ、それをファイアベースに保存するだけです。 – Edmund

+1

ブライアンのポイントは、何も返されていない場合です。それでは、プロミスを返すことはありません。:)あなたのsaveLocationsとinstallWebhookForLocationsは約束を返しますか? – Keith

答えて

1

は約束を使用するsaveMerchantの一例です。

function saveMerchant(merchant_id, access_token, locations) { 
    return new Promise(function (resolve, reject) { 
    const merchantRef = database.ref('merchants').child(merchant_id); 
    const location_ids = locations.map(location => location.id); 

    merchantRef.update({ 
     access_token, 
     location_ids, 
    }, function (error) { 
     if (error) return reject(error); 
     resolve(); 
    }); 
    }); 
} 

上記やすくするために、ブルーバードと呼ばれる素敵な約束ライブラリがあり、それはあなたがFirebirdの更新方法に適用することができることを、promisify有用性を有します。

また、あなたの2番目の質問にはforEachを使用していましたが、bluebirdには代わりに使用できるmapという素晴らしいユーティリティ関数があります。

+0

私はリクエストコールバックに対して同じことをすることができますか? – Edmund

+0

はい、約束のベースのリクエストlibもあります。これは、リクエストを約束したより多くのことを行い、ストリームを約束として扱います。 - > https://www.npmjs.com/package/request-promise基本的に、非同期メソッドのコールバックを持つものは約束できます。 – Keith

+0

約束が本当に素晴らしいのは、 'async'や' await'のような新しいES6の機能は、物事をより良くすることを約束していることです。 – Keith

関連する問題