【问题标题】:How to wrap function call inside of Promise如何在 Promise 中包装函数调用
【发布时间】:2021-09-14 11:34:02
【问题描述】:

导出所需模块并设置变量后

let AWS = require("aws-sdk");
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');

const USER_POOL_ID = 'us-east-1_vkXRQuP4U';
const CLIENT_ID = 'mipa4trls0l7323om33mlk80e8';

const poolData = { 
  UserPoolId : USER_POOL_ID, ClientId : CLIENT_ID
};
const POOL = new AmazonCognitoIdentity.CognitoUserPool(poolData);

let email = "my.email@domain.com";
let password = "My.Password!";

我可以继续调用signUp 命令:

POOL.signUp(email, password, [], null, function(err, result) {
  console.log('...result:', result);
});

而且效果很好。接下来我想将POOL.signUp(email, password...) 包裹在async 函数sign_up 中,如下所示:

async function sign_up(email, password) {
  POOL.signUp(email, password, [], null, function(err, result) {
    console.log('...sign_up.result:', result);
    return result;
  })
};

async function main() {
  let signupData = await sign_up(email, password);
  console.log('...main.signupData:', signupData);
  return signupData;
};

main().then((error, data) => {console.log('...error, data:', error, data)});

虽然它工作正常,但调用的执行顺序是错误的,因为 main 函数不会等待 sign_up() 函数完成。为了纠正这种行为,我将 POOL.signUp(email, password...) 包装在 Promise 中:

async function sign_up(email, password) {

  return await new Promise((resolve) => {
    POOL.signUp(email, password, [], null, {
      onSuccess: (result) => {
        console.log('...result:', result)
        return resolve(result);
      },      
      onFailure: (err) => {
        return resolve(err.message);
      },
    });
  })
};

但我收到错误消息:

 UnhandledPromiseRejectionWarning: TypeError: callback is not a function

有没有办法避免这个错误?

【问题讨论】:

    标签: javascript node.js amazon-web-services amazon-cognito


    【解决方案1】:
    • 不需要await 你返回的 Promise(因为我们确实希望我们的函数是异步的,所以我们希望将等待推迟到调用者)
    • Promise构造函数需要提供第二个reject参数才能在函数实现中访问回调
    • 将回调函数作为POOL.signUp 的第四个参数而不是对象传递
    function sign_up(email, password) {
      return new Promise((resolve, reject) => {
        POOL.signUp(email, password, [], null, function(err, result) {
          if (err) {
            return reject(err.message);
          }
    
          console.log('...result:', result)
          resolve(result);
        });
      })
    };
    

    【讨论】:

    • 我已经删除了async——一个直接返回promise的函数不需要它。在reject() 之后返回也是个好主意。
    • 欣赏编辑。我忘记了控制流中的返回,我移动了它,以便它只返回拒绝呼叫结果(出于文体原因)。
    • 那么在这种情况下,if (err) return reject(err.message); 就更加巧妙了。 :)
    • 可以说 node.js 最优雅的解决方案是const { promisify } = require('util');POOL.signUpAsync = promisify(POOL.signUp);。无需手动承诺功能。
    • 当 OP 真正感兴趣时,他们会从 cmets 中获取。
    猜你喜欢
    • 2017-05-18
    • 2015-05-13
    • 2018-05-17
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多