我有一个名为 fetchMerchantData
的方法,它调用其他 3 个异步方法。我正在尝试使用 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");
})
}
});
}
这是调用 firebase 的 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();
});
});
}
为了使上述操作变得更容易,有一个名为 Bluebird 的不错的 Promise 库,它有一个 promisify 实用程序,您可以将其应用于 firebird 更新方法。
另外,对于你的第二个问题,你使用的是 forEach,bluebird 有一个很好的实用函数,称为 map,你可以使用它。
关于javascript - Node + ES6 : How to use Promise. 全部带有异步请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40474291/