Nodejs 异步方法x有返回值,那么y = x()的赋值是什么时候进行?

Nodejs 异步方法x有返回值,那么y = x()的赋值是什么时候进行?

如最下面大段代码中有一句: ok = writer.write(data, encoding,function(){console.log(‘因为是异步,所以i都是0:’ , i);}); 这一句的write方法是异步,ok初始为false,那么在紧接着的下一句console.log(ok)中,ok应该为true还是false? 如果ok是false那么说明ok的赋值至少要在下一个事件循环里, 如果ok是true那么说明这个异步方法已经完成了?!并且有返回值。 实际是true,我就搞不懂了,不知道怎么理解。

var fs = require(‘fs’); var w = fs.createWriteStream(‘txt.txt’);

writeTimes(w,‘utf8’,function(){console.log(‘完成’);});

function writeTimes(writer, encoding, callback) { var data = ‘’; var i = 10; write(); function write() { var ok = false; do { ok = false; data =new Date().getTime().toString() + ‘\n’; i -= 1; if (i === 0) { // last time! writer.write(data, encoding, callback); } else { ok = false; ok = writer.write(data, encoding,function(){console.log(‘因为是异步,所以i都是0:’ , i);}); console.log(‘write方法外,第 %d 次,write的返回: %s’ ,10-i, ok.toString()); } } while (i > 0 && ok); if (i > 0) { // had to stop early! // write some more once it drains writer.once(‘drain’, write); } } }


10 回复

Node.js 异步方法x有返回值,那么y = x()的赋值是什么时候进行?

问题描述

假设有一个异步方法 x(),该方法执行时会立即返回一个值。如果我们这样写 y = x()y 的赋值会在什么时候发生?

示例代码

让我们通过一个具体的例子来理解这个问题。

const fs = require('fs');

// 创建一个写入流
const writer = fs.createWriteStream('output.txt');

// 定义一个函数用于写入数据
function writeData(writer, encoding, callback) {
    let data = '';
    let i = 5;

    function write() {
        let ok = false;
        do {
            ok = false;
            data = new Date().getTime().toString() + '\n';
            i -= 1;
            if (i === 0) {
                // 最后一次写入
                writer.write(data, encoding, callback);
            } else {
                ok = writer.write(data, encoding, () => {
                    console.log(`异步操作完成,i = ${i}`);
                });
            }
        } while (i > 0 && ok);

        if (i > 0) {
            // 如果写入未完成,等待流可写后再继续
            writer.once('drain', write);
        }
    }

    write();
}

// 调用写入数据的函数,并传入回调
writeData(writer, 'utf8', () => {
    console.log('所有数据已写入');
});

// 在写入数据函数调用后打印ok
console.log('ok的值:', ok); // 注意:此时ok的值可能不是最终结果

解释

  1. 异步方法的返回值:在上面的代码中,writer.write(data, encoding, callback) 是一个异步方法。它会立即返回一个布尔值 ok,表示当前是否可以继续写入数据。如果 okfalse,则表示当前写入缓冲区已满,需要等待 'drain' 事件触发后再继续写入。

  2. 赋值时机:当调用 y = x() 这样的语句时,y 的赋值是在当前执行栈结束之后,即在当前函数执行完之后进行的。对于异步方法来说,y 的赋值会在异步操作完成之前进行,因此你可能会看到不完整的或预期之外的结果。

  3. 回调机制:为了确保异步操作完成后执行某些逻辑,我们通常使用回调函数。例如,在上面的例子中,writer.write 方法的第三个参数是一个回调函数,当写入操作完成后会调用这个回调函数。

  4. 事件循环:JavaScript 使用事件循环机制来处理异步操作。当异步操作完成时,相应的回调函数会被推入事件队列中,等待事件循环的下一轮迭代来执行。

因此,在上述代码中,ok 的赋值发生在异步操作完成之前,这意味着 ok 的值可能是不准确的,除非你在回调函数内部进行赋值和后续处理。


OK = writer.writer() 因为没有RETURN 而writer函数的writer方法存在故返回TRUE?

我猜的。你的写法我看的太累了23333。

异步方法x有返回值,那么y = x()的赋值是什么时候进行? 如果X()是同步函数,那Y会等待X的返回值的。是异步会返回UNDEFINED貌似?。

这个是网上的实例,我就直接拿过来了。

改简单了点,可以直接考到一个js,然后Node一下就看结果

var fs = require(‘fs’); var w = fs.createWriteStream(‘txt.txt’); var data = ‘’; var i = 10; var ok = false;

do { ok = false; data =new Date().getTime().toString() + ‘\n’; i -= 1; ok = w.write(data, ‘utf8’,function(){console.log(‘因为是异步,所以i都是0:’ , i);}); console.log(‘write方法外,第 %d 次,write的返回: %s’ ,10-i, ok.toString()); } while (i > 0 && ok);

write方法是有返回值的。

自己顶

继续顶

callback的执行和异步函数的返回没有关系。

函数就是函数,不管是同步还是异步的,x代码里return的是什么,y=x()在执行时y就被赋值为什么

根据你提供的代码和问题,我们可以分析一下 ok 的赋值时机。

在 Node.js 中,异步操作的结果通常会在回调函数中处理。在你的例子中,writer.write 是一个异步方法,其返回值 ok 表示当前写入是否成功,但这并不意味着整个异步操作已经完成。

具体来说:

  1. 异步操作的立即返回:当你调用 writer.write 方法时,它会立即返回一个布尔值 ok。这个值表示当前写入操作是否可以继续执行(即是否还有缓冲空间),而不是表示写入操作是否完成。

  2. 回调函数中的操作writer.write 方法接受一个回调函数作为参数,该回调函数会在写入操作完成后被调用。在这个回调函数中,你可以知道写入操作是否真的完成了。

下面是修改后的代码示例:

var fs = require('fs');

var w = fs.createWriteStream('txt.txt');

writeTimes(w, 'utf8', function() { console.log('完成'); });

function writeTimes(writer, encoding, callback) {
    var data = '';
    var i = 10;

    write();

    function write() {
        var ok = false;
        do {
            ok = false;
            data = new Date().getTime().toString() + '\n';
            i -= 1;
            if (i === 0) {
                // 最后一次
                writer.write(data, encoding, callback);
            } else {
                ok = writer.write(data, encoding, function() {
                    console.log('因为是异步,所以i都是0:', i);
                });
                console.log('write方法外,第 %d 次,write的返回: %s', 10 - i, ok.toString());
            }
        } while (i > 0 && ok);

        if (i > 0) {
            // 如果需要停止早期操作
            // 当缓冲区清空后继续写入
            writer.once('drain', write);
        }
    }
}

console.log('write方法外,第 %d 次,write的返回: %s', 10 - i, ok.toString()); 这一行中,ok 的值取决于当前写入操作是否能够立即执行。它并不是最终的写入完成状态,而是当前写入是否成功的标志。

为了更好地理解异步操作的完成情况,你应该关注回调函数或事件触发的逻辑,而不是立即返回的 ok 值。

回到顶部