3

我知道 node.js 是异步运行的,所以外部函数比内部函数执行得早。但是在 for 循环之外访问通知数组的方法是什么?我想一次访问数组中的所有值,这可行吗?

var notification=[];

for(var j=0;j<6; j++)
{
     getNotification(response[j].sender_id,function(results)     // a function called
     {
         notification[j] =results;
         console.log(notification); // output: correct   
     });          
}
console.log(notification);       // output: [], need notification array values here
4

3 回答 3

1

编辑:如果您不想使用第三方库,这是在您自己的代码中执行此操作的方法。

/* jshint node:true*/


function getNotifications(responses, callbackToMainProgramLogic) {
    'use strict';
    var results = [];

    function getNotificationAsync(response) {
        getNotification(response.sender_id, function (data) {
            results.push(data);

            if (responses.length) {
                getNotificationAsync(responses.pop());//If there are still responses, launch another async getNotification.
            } else {
                callbackToMainProgramLogic(results);//IF there aren't we're done, and we return to main program flow
            }
        });
    }

    getNotificationAsync(responses.pop());
}

getNotifications(someArrayOfResonses, function (dataFromNotifications) {
    console.log('The collected data: ' + JSON.stringify(dataFromNotifications, 0, 4));
});

如果你绝对必须,你可以做一些像这样荒谬的事情。您在 loopUntilDatReceived 中的逻辑将等待数组大小,而不是等待非空字符串,但想法是相似的,无论如何您都不应该使用它!:)

var fileData = '';
fs.readFile('blah.js', function (err, data) { //Async operation, similar to your issue.
    'use strict';
    fileData = data;
    console.log('The Data: ' + data);
});

function loopUntilDataReceived() {
    'use strict';
    process.nextTick(function () {//A straight while loop would block the event loop, so we do this once per loop around the event loop.  
        if (fileData === '') {
            console.log('No Data Yet');
            loopUntilDataReceived();
        } else {
            console.log('Finally: ' + fileData);
        }
    });
}

loopUntilDataReceived();

我有没有提到这很荒谬?老实说,这是一个糟糕的想法,但它可以帮助您了解正在发生的事情以及 Node 事件循环是如何工作的,以及为什么您想要的东西是不可能的。以及为什么其他关于回调和流控制库的帖子是要走的路。

于 2013-08-02T13:35:16.810 回答
0

像这样向通知循环发送回调:

var notification=[];

getNotificationArray( function() {
  console.log(notification);
});

function getNotificationArray (callback)
{
  for(var j=0;j<6; j++)
  {
    getNotification(response[j].sender_id,function(results)     // a function called
    {
      notification[j] =results;
      console.log(notification); // output: correct   
    });          
  }
  callback();
}
于 2013-08-02T13:32:25.100 回答
0

首先,您的代码中存在关闭问题(请参阅此处的详细信息)

然后,您根本无法将数组值放在循环旁边,因为此时值还没有准备好。您需要等到所有 6 个 getNotification 调用都得到解决。您可以使用异步库来做到这一点。就像是:

var notification = [];

function createRequest (index) {
    return function (callback) {
        getNotification(response[index].sender_id, function(results) {
            notification[index] = results;
            callback(results);
        });
    }
}

var requests = [];
for(var j=0;j<6; j++) {
    requests.push(createRequest(j));
}

async.parallel(requests, function (allResults) {
    // notifications array is ready at this point
    // the data should also be available in the allResults array
    console.log(notifications);
});
于 2013-08-02T13:34:03.050 回答