0

我正在设置一个 GraphQL 解析器来调用 Braintree 端点。Braintree npm 包希望使用如下代码调用其端点:

braintreeGateway.customer.create({
    firstName: "Jen",
    lastName: "Smith",
    company: "Braintree",
    email: "jen@example.com",
    phone: "312.555.1234",
    fax: "614.555.5678",
    website: "www.example.com"
}, function (err, result) {
    result.success;
    result.customer.id;
});

GraphQL 解析器返回承诺。我试图弄清楚如何承诺这个回调,并将它包含在一个承诺解析器中。

我已经阅读了很多关于承诺回调的 SO 帖子,但到目前为止我发现的那些似乎与这个用例不太匹配。

我已经尝试了很多东西,这是最新的:

getBrainTreeCustomerId: (parent, args, context) => {
    const userid = context.userId;

    const braintreeCustomerCreate =  util.promisify(braintreeGateway.customer.create);

    async function run_braintreeCustomerCreate() {
        try {
            let braintreeCustomerId = await braintreeCustomerCreate({
                firstName: "Jen",
                lastName: "Smith",
                company: "Braintree",
                email: "jen@example.com",
                phone: "312.555.1234",
                fax: "614.555.5678",
                website: "www.example.com"
            });
            return braintreeCustomerId
        }
        catch (err) {
            console.log('ERROR:', err);
        }
    }

    return Promise.resolve()
        .then(() => {
            let braintreeCustomerId = (async () => {
                let braintreeCustomerId = await run_braintreeCustomerCreate()
                return braintreeCustomerId;
            })();
            return braintreeCustomerId;
        })
        .then((braintreeCustomerId) => {
            return braintreeCustomerId;
        })
        .catch((err) => {
            console.log(err);
        });
}
}

但是 catch 处理程序收到一条错误消息,提示“无法读取未定义的属性 '_createSignature'”。

在这里使用的正确语法是什么?

4

2 回答 2

0

问题是,如果您不将 promisified 函数作为方法调用,则该this值未绑定在方法中。create

const braintreeCustomerCreate = util.promisify(braintreeGateway.customer.create.bind(braintreeGateway.customer));
//                                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

getBrainTreeCustomerId: async (parent, args, context) => {
    const userid = context.userId;

    try {
        let braintreeCustomerId = await braintreeCustomerCreate({
            firstName: "Jen",
            lastName: "Smith",
            company: "Braintree",
            email: "jen@example.com",
            phone: "312.555.1234",
            fax: "614.555.5678",
            website: "www.example.com"
        });
        return braintreeCustomerId;
    }
    catch (err) {
        console.log('ERROR:', err);
        return null;
    }
}
于 2020-04-18T21:19:56.350 回答
0

BrainTree通过将 promisified 函数设置在网关范围之外,您可能会将其与对象结构分离太多。该错误听起来像是在尝试访问不再在范围内的另一个内部函数。试试这个而不使用util.promisify

async function run_braintreeCustomerCreate() {
  return new Promise((resolve, reject) => {
    braintreeGateway.customer.create( 
      {
        firstName: "Jen",
        lastName: "Smith",
        company: "Braintree",
        email: "jen@example.com",
        phone: "312.555.1234",
        fax: "614.555.5678",
        website: "www.example.com"
      },
      (err, result) => {
        if (err) return reject(err);
        return resolve(result);
      }
    );
  });
}

这将返回一个 Promise,该 Promise 在以与对象一致的方式调用时根据调用结果解析或拒绝。

另一种可行的方法是promisified 函数添加到客户对象,如下所示:

const createAsPromise = util.promisify(braintreeGateway.customer.create);
braintreeGateway.customer.createAsPromise = createAsPromise;

async function run_braintreeCustomerCreate() {
  try {
    let braintreeCustomerId = await braintreeGateway.customer.createAsPromise(
      { /* data */ }
    ); 
    return braintreeCustomerId;
  }
  catch(err) console.log('ERROR:', err);
}          

作为一般说明,您不需要在链中更早地进行捕获,因为.catch它将起作用,并且它通过完全消除对的需求来简化您的逻辑try。另请注意,从create调用返回的对象将包含一个 Id,但它本身不仅仅是 Id - 它是一个对象。事实上,使用trywithcatch会阻止调用它的人看到错误,因为它最终不会返回任何内容(即undefined)作为解析的值。

于 2020-04-18T18:54:17.160 回答