学习nodejs过程中方法执行同步还是异步,怎么回避回调简单总结

avatar

学习nodejs的新手应该都碰到过这种问题

  1. 调用一个方法,它到底是同步的还是异步的呢?有什么特征能区分吗?
  2. 有什么办法能回避掉回调吗?

下面就来说说我这两天的理解,希望能对同样处于迷茫状态下的你有所帮助

昨天在v2和cnodejs上发了两个帖子,跟大佬们讨教了一下,在这稍微总结一下

首先关于上面第一个问题 它到底是同步的还是异步的呢?有什么特征能区分吗? 目前的答案是除了方法的注释或者文档里有明确的说明这个方法是同步的还是异步的,或者从方法的名字来识别以外,没有其它办法能判断一个方法是同步执行还是异步执行,比如 fs.readFileSync() fs.readFile() 很容易就能看出来它们是同步还是异步的了

关于第二个问题,回避回调现在有两种方法,一个是 Promise 另一个是 async/await

把一个方法包装成 Promise 对象就可以通过 .then() 方法的回调来拿方法执行的结果了,细想一下,不对呀,这换汤不换药呀,回避了方法的回调,却把回调放在了 .then() 方法里,这不是没有回避吗,我觉得这里用Promise对象的目的应该就是让代码可读性更高而已,至于回调还是要用的,代码如下

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
  });
}

timeout(100).then((value) => {
  console.log(value);
});

至于 async/await ,它的前身是 Generator ,Generator的用法是 */yield ,而且 Generator使用过程中还要依赖解析库,比如 co,例子如下

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();

但在ES7里,引入了async/await,它不需要依赖第三方解析库了,拿来就可以用,更方便了,而且关键字名也换了,语义上更清楚了,举个例子

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

从上面可以看出来,async/await修饰的函数都是Promise对象,所以这里可以得出一个结论,async/await只有用在被包装成Promise对象的函数上才有意义

包装Promise对象还有个规则,就是原方法的回调参数里第一个必须要是 error 对象

至于包装Promise对象,nodejs官方文档里也给出了一个工具类,一行代码就能包装成一个Promise对象,地址:https://nodejs.org/api/util.html#util_util_promisify_original

用法如下

const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);
stat('.').then((stats) => {
  // Do something with `stats`
}).catch((error) => {
  // Handle the error.
});

文档下面还给出了结合async/await的用法

const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);

async function callStat() {
  const stats = await stat('.');
  console.log(`This directory is owned by ${stats.uid}`);
}

以上总结是结合了两篇帖子和阮老师的ECMAScript 6 入门教程总结的,如有不对,还请指出

目前还没有回答,快来帮帮TA吧!
添加一条评论 请尽量发布对他人有帮助的评论

登录后可发布评论

登录 | Github登录