await-to-js源码学习

众所周知 await可以帮我省略一些无聊的 .then代码,但是这玩意没有自带.catch功能。

如果不用 await的话,我们直接可以Promise.catch捕获错误,不用写try catch

// let result = { success: true, data: [] };
let result = { success: false, error:'something went wrong' };

new Promise((resolve, reject) => {
  if (result.success) {
    resolve(result.data);
  }
  reject(new Error(result.error));
})
  .then((data) => console.log(data))
  .catch((err) => console.log(err));

但是await并没有.catch的功能!

在没有错误的时候,我们直接使用toplevel的await获取数据直接爽死。

let result = { success: true, data: [] };

let promise = new Promise((resolve, reject) => {
  if (result.success) {
    resolve(result.data);
  }
  reject(new Error(result.error));
});

const data = await promise;
console.log(data)

但是存在错误的时候,我们就必须用 try catch

let result = { success: false, error: "something went wrong" };

let promise = new Promise((resolve, reject) => {
  if (result.success) {
    resolve(result.data);
  }
  reject(new Error(result.error));
});

try {
  const data = await promise;
} catch (err) {
  console.log(err);
}

当只有一个await时,我们写try catch代码块是完全可以接受的,但是多了之后代码就会长这个样子:

async function asyncTask(cb) {
    try {
       const user = await UserModel.findById(1);
       if(!user) return cb('No user found');
    } catch(e) {
        return cb('Unexpected error occurred');
    }

    try {
       const savedTask = await TaskModel({userId: user.id, name: 'Demo Task'});
    } catch(e) {
        return cb('Error occurred while saving task');
    }

    if(user.notificationsEnabled) {
        try {
            await NotificationService.sendNotification(user.id, 'Task Created');  
        } catch(e) {
            return cb('Error while sending notification');
        }
    }

    if(savedTask.assignedUser.id !== user.id) {
        try {
            await NotificationService.sendNotification(savedTask.assignedUser.id, 'Task was created for you');
        } catch(e) {
            return cb('Error while sending notification');
        }
    }

    cb(null, savedTask);
}

这时候,2位伟大的天才就想出一个很简单的解决方法,就几行代码,就让我们不用写 try catch代码块了。

在这里插入图片描述

他就是十分巧妙地使用了promise自带的catch功能!

// to.js
export default function to(promise) {
   return promise.then(data => {
      return [null, data];
   })
   .catch(err => [err]);
}
export default to;

如果我们想要给catch传递传递给多的错误信息,代码就长这个样子:

/**
 * @param { Promise } promise
 * @param { Object= } errorExt - Additional Information you can pass to the err object
 * @return { Promise }
 */
function to(promise, errorExt) {
    return promise
        .then(function (data) { return [null, data]; })
        .catch(function (err) {
        if (errorExt) {
            Object.assign(err, errorExt);
        }
        return [err, undefined];
    });
}
export default to;

想要使用这个玩意,也很简单:

import { to } from "await-to-js";

let result = { success: true, data: [] };
// let result = { success: false, error: "something went wrong" };

let promise = new Promise((resolve, reject) => {
  if (result.success) {
    resolve(result.data);
  }
  reject(new Error(result.error));
});

// 把promise对象作为参数传入to中
const [err, data] = await to(promise);
// 如果是成功获取的,返回的格式是 [null,data]
// 如果是失败获取 返回的格式是[err,undefined]
if (err) console.log(err)
else{
  console.log(data)
}

总之,这个作者的想法很巧妙,对js语法的理解也很深刻。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值