节点+ ES6:如何使用Promise.all与asynchronous请求?

我有一个名为fetchMerchantData的方法,它调用3个其他的asynchronous方法。 我试图使用Promise ,它不会调用resp.direct(301, ...)直到所有的请求完成,但它不工作。

 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"); }) } }); } 

这里有一个调用saveMerchant方法的例子:

 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, }); } 

我将如何同步呢?

==更新==

这是我的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}`); } }); }); } 

这是一个使用promise的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(); }); }); } 

为了使上述更容易,有一个很好的Promise库叫做Bluebird,它有一个promisify工具,你可以应用到firebird的更新方法。

另外对于你的第二个问题,你使用forEach,蓝鸟有一个很好的实用function称为地图,你可以使用。