javascript - Node + ES6 : How to use Promise. 全部带有异步请求?

标签 javascript node.js

我有一个名为 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/

相关文章:

同一文档中的 PHP GET 变量

javascript - iOS 的视频自动播放无法在应用程序中运行

javascript - 我可以在原型(prototype)方法中修改字符串的内容吗?

javascript - 如何过滤mongoDB中的子文档?

node.js - 获取node.js中所有嵌套子进程的标准输出

javascript - 如何返回一个对象而不是数组?

javascript - 在 Angularjs 中通过 IP 地址获取用户的位置

javascript - jQuery UI 警报对话框作为alert() 的替代品

javascript - 将包含单个反斜杠的 Javascript 字符串拆分为两个字符串

javascript - 用户登录时如何 'remember' -passport.js-phonegap