Nodejs 如何把方法写成异步?

Nodejs 如何把方法写成异步?

function get_all_categories(callback){
function sleep(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
}
sleep(10000);
callback();};

这个方法让他sleep10秒,但是一个一面调用他之后,后面访问的页面也要等10秒了,不解,这不是异步的写法么?


11 回复

当然可以。首先我们需要澄清一点:上述代码并不是真正的异步编程。它使用的是阻塞方式(通过 while 循环)来模拟延迟,这种方式会导致调用者必须等待该函数执行完毕才能继续执行后续代码。真正的异步编程应该避免这种情况,让调用者能够在等待期间继续执行其他任务。

接下来,我会展示如何将 get_all_categories 方法改写为真正的异步方法,并结合使用 setTimeout 来模拟异步操作,例如数据库查询或网络请求。

示例代码

// 异步函数示例
function get_all_categories(callback) {
    // 模拟一个耗时的异步操作,如数据库查询
    setTimeout(() => {
        const categories = ["Electronics", "Clothing", "Books"];
        callback(null, categories); // 成功回调
    }, 10000); // 模拟10秒的延迟
}

// 使用示例
get_all_categories((err, categories) => {
    if (err) {
        console.error('Error fetching categories:', err);
    } else {
        console.log('Fetched categories:', categories);
    }
});

解释

  1. setTimeout: 这个函数用于设置一个定时器,在指定的毫秒数后执行一个函数。这里我们使用它来模拟一个耗时的异步操作。

  2. callback: 当异步操作完成时,我们将结果传递给 callback 函数。这允许我们在操作完成后处理结果。如果过程中出现错误,则第一个参数通常是一个错误对象;如果没有错误,则第二个参数包含操作的结果。

  3. 异步行为: 在上面的代码中,即使 get_all_categories 函数需要10秒才能完成,其他JavaScript代码仍然可以在这段时间内执行。这是因为 setTimeout 是非阻塞的,它不会阻止事件循环,从而允许其他任务在等待期间运行。

  4. 回调地狱: 虽然这种方法有效,但当多个异步操作串联在一起时,可能会导致回调嵌套过多(也称为“回调地狱”)。为了改善这一点,可以考虑使用Promises或者async/await语法。

希望这段解释和示例能帮助你理解如何在Node.js中编写异步方法。


是异步, 但是 while 循环把 CPU 卡死了, setTimeout 才可以

setTimeout本身是一个异步函数,我要自己写一个异步函数怎么写?

这不是异步~这只是一个简单的回调而已!不是回调就是异步的~

function get_all_categories(callback){
  setTimeout(10000, callback);
}

把回调交给setTimeout,然后__立即返回__,定时器到期后自动调用。

这样的做法才是异步,困在一个函数内不返回绝不能称作异步。

把别人交给你的回调函数转发给setTimeout或者process.nextTick(相当于setTimeout(0)

这个不太可能用javascript来实现,这个函数实际上是C实现的

可以的, 你可以测试下这个冒泡代码

https://gist.github.com/sonygod/5362041
function asy(callback){
    setTimeout(callback,10000);
}

如果想要异步,在js里面应该只能用cb来做

我记得源码中有一段就是能把同步的方法变成异步的

你的当前实现是同步的,并且阻塞了主线程。为了让这个方法变成异步的,你可以使用回调函数、Promise 或者 async/await。

示例 1:使用回调函数

function get_all_categories(callback) {
    setTimeout(() => {
        // 模拟耗时操作
        callback(null, ["Category 1", "Category 2", "Category 3"]);
    }, 10000);  // 延迟10秒
}

// 调用
get_all_categories((err, categories) => {
    if (err) {
        console.error(err);
    } else {
        console.log(categories);
    }
});

示例 2:使用 Promise

function get_all_categories() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 模拟耗时操作
            resolve(["Category 1", "Category 2", "Category 3"]);
        }, 10000);  // 延迟10秒
    });
}

// 调用
get_all_categories()
    .then(categories => console.log(categories))
    .catch(error => console.error(error));

示例 3:使用 async/await

function get_all_categories() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 模拟耗时操作
            resolve(["Category 1", "Category 2", "Category 3"]);
        }, 10000);  // 延迟10秒
    });
}

async function fetchCategories() {
    try {
        const categories = await get_all_categories();
        console.log(categories);
    } catch (error) {
        console.error(error);
    }
}

// 调用
fetchCategories();

这些示例展示了如何将同步操作转换为异步操作,避免阻塞主线程。

回到顶部