Nodejs 求大神帮忙 forEach里循环发请求 如何控制最终回调

Nodejs 求大神帮忙 forEach里循环发请求 如何控制最终回调

我有这样一个需求,利用request 向一个服务器发请求获取数据,例如我有一个url_list, 这里面放的是各种抓数据的url,然后做其他的逻辑 ,我利用了async; 我想到的方法是:

async.waterfall([ function(callback){ url_list.forEach(function(url){ request(url,(e, r, json) { 想要的数据 ===json里面的数据 callback(全部数据) }); }); }, 其他的逻辑(例如渲染页面)

但是这样我怎么控制回调呢,也是等待所有的请求返回后,采取执行callback,有什么方式 或者库都请,求大神帮忙, 我是node新手


5 回复

当然可以。根据你的需求,你希望在 forEach 循环中向多个 URL 发送请求,并且在所有请求完成之后再进行下一步操作。这里我们可以使用 async/await 结合 Promise 来实现这个功能。下面是具体的解决方案:

示例代码

const request = require('request');
const async = require('async');

// 假设这是你的 URL 列表
const url_list = [
    'http://example.com/data1',
    'http://example.com/data2',
    'http://example.com/data3'
];

// 使用 async 和 await 来处理异步操作
async function fetchAllData() {
    // 创建一个空数组来存储所有的请求结果
    let allData = [];

    // 使用 Promise.all 来并行处理所有请求
    const promises = url_list.map(async (url) => {
        return new Promise((resolve, reject) => {
            request(url, (error, response, body) => {
                if (error) {
                    reject(error);
                } else {
                    resolve(JSON.parse(body)); // 假设响应体是 JSON 格式
                }
            });
        });
    });

    try {
        // 等待所有请求完成
        const results = await Promise.all(promises);

        // 将所有数据合并到一个数组中
        results.forEach(result => {
            allData.push(result);
        });

        // 打印或者处理所有的数据
        console.log(allData);

        // 在这里进行其他的逻辑,例如渲染页面
        // 其他逻辑...

    } catch (error) {
        console.error('Error fetching data:', error);
    }
}

// 调用函数
fetchAllData();

解释

  1. 使用 Promise:

    • 我们将每个请求封装成一个 Promise,这样我们就可以使用 Promise.all 来并行处理所有的请求。
  2. Promise.all:

    • Promise.all 方法接收一个 Promise 数组,并返回一个新的 Promise。当所有的 Promise 都成功解决时,新的 Promise 会成功解决;如果有任何一个 Promise 被拒绝,新的 Promise 也会被拒绝。
  3. async/await:

    • 使用 async/await 可以使异步代码看起来更像同步代码,更容易理解和维护。
  4. 错误处理:

    • 使用 try/catch 来捕获和处理可能发生的错误,确保程序的健壮性。

通过这种方式,你可以确保所有的请求都在所有数据收集完毕后再进行下一步的操作。希望这能帮助你解决问题!


习惯一下回调吧, 就算不喜欢用, 文档也会有回调写的.

then.js的写法如下:

// url_list 为数组
then.each(url_list, function (defer, url) {
    request(url, function (err, res, json) {
        defer(err, json)
    })
}).then(function (defer, result) {
    // result 就是url获取的json结果数组,顺序与url对应
}).fail(function (defer, err) {
    // 处理 err
})

https://github.com/teambition/then.js 目前teambition.com前端和angularjs.cn的后端采用的then.js

在外面多嵌套一个

var work = async.waterfall([
function(callback){
url_list.forEach(function(url){
   request(url,(e, r, json) {
   想要的数据 ===json里面的数据
   callback(全部数据)
  });
});

async.forEach(list, work, function(){ //fin work })

要在一个 forEach 循环中处理多个异步请求,并确保所有请求完成后再进行后续操作,可以使用 async/await 结合 Promise.all 来实现。这里提供一个示例代码,展示如何使用这些技术来控制回调。

首先,确保安装了必要的库:

npm install request

然后,可以编写如下的代码:

const request = require('request');

// url列表
const url_list = [
    'http://example.com/data1',
    'http://example.com/data2',
    // 更多URL...
];

// 使用Promise封装request调用
function fetchUrl(url) {
    return new Promise((resolve, reject) => {
        request(url, (error, response, body) => {
            if (error) {
                reject(error);
            } else {
                resolve(JSON.parse(body)); // 假设返回的是JSON格式数据
            }
        });
    });
}

// 异步函数处理所有URL请求
async function processUrls() {
    try {
        // 使用map创建Promise数组
        const promises = url_list.map(fetchUrl);

        // 等待所有Promise完成
        const results = await Promise.all(promises);

        // 处理结果
        console.log(results); // 打印所有结果

        // 其他逻辑
        // 例如渲染页面
        renderPage(results);
    } catch (error) {
        console.error("Error processing URLs:", error);
    }
}

// 渲染页面函数示例
function renderPage(data) {
    // 实现你的渲染逻辑
    console.log("Rendering page with data:", data);
}

// 调用处理函数
processUrls();

解释

  • fetchUrl 函数将 request 包装成一个返回 Promise 的函数,这样我们可以方便地使用 await
  • processUrls 函数中,我们使用 Array.prototype.map 创建一个包含所有请求的 Promise 数组。
  • Promise.all 等待所有 Promise 完成,并返回一个包含所有结果的数组。
  • 所有请求完成后,你可以继续执行其他逻辑,比如渲染页面。

这种方法能够有效地管理异步操作,并确保所有请求完成后再进行后续处理。

回到顶部