最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

如何解决麻烦的for循环和承诺没有异步等待

IT培训 admin 2浏览 0评论

如何解决麻烦的for循环和承诺没有异步/等待

我正在努力争取循环和承诺,而不使用async / await(这在我最初运行的azure函数版本上不可用,我还没有将我的所有代码转移到更新的版本)我在json文件上检查我的数据库在每个json中,我想看看2个不同数组中包含的URL是否仍然有效。然后,如果url已过期,我想将该json id推入容器以处理稍后/更新。

目前我正在努力尝试每个json测试2个独立的数组。

module.exports = function(context, req) {
    getJsons(context, function(res) {
        createContainer(context, res)
    });
}

function getJsons(context, callback) {
    context.log('start');
    client.queryDocuments(
        collectionUrlJsons,
        `SELECT * FROM r`
    ).toArray((err, results) => {
        if (err) {
            context.log(err);
            context.done();
        } else {
            context.log(results.length + " jsons");
            // now I have all JSONs in an array
            analyse(context, results, function(result) {
                callback(result);
            })
        }
    });
}

function analyse(context, results) {
    var editArr = [];
    for (i = 0; i < results.length; i++) {
        var arr = [];
        var loopPhotos = checkPhotos(context, results[i].photos);
        var loopVideos = checkVideos(context, results[i].videos);
        Promise.all([loopPhotos, checkVideos]).then(function(result) {
            if (result[0].length > 0) {
                context.log('photos expired')
                arr.push('photo');
            }
            if (result[1].length > 0) {
                context.log('videos expired')
                arr.push('video');
            }
        });
        if (arr.length > 0) {
            editArr.push(results[i].id);
        }
    }
    return Promise.all(editArr);
}

function checkPhotos(context, photos) {
    var arr = [];
    for (i = 0; i < photos.length; i++) {
        var link = photos[i].latestUrl;
        request(link, function(error, response, body) {

            if (response.statusCode == 403) {
                arr.push("photo: " + body);
            }

        });
    }
    return Promise.all(arr);
}

function checkVideos(context, videos) {
    var arr = [];

    context.log(videos)
    for (i = 0; i < videos.length; i++) {
        var link = videos[i].latestUrl;
        request(link, function(error, response, body) {
            if (response.statusCode == 403) {
                arr.push("video: " + body);
            }

        });
    }
    return Promise.all(arr);
}
function createContainer(context, jsons) {
    //code
}

编辑下面反映评论 - 将if (arr.length >0)放入Promise.allfunction analyse

module.exports = function(context, req) {
    getJsons(context, function(res) {
        createContainer(context, res)
    });
}

function getJsons(context, callback) {
    context.log('start');
    client.queryDocuments(
        collectionUrlJsons,
        `SELECT * FROM r`
    ).toArray((err, results) => {
        if (err) {
            context.log(err);
            context.done();
        } else {
            context.log(results.length + " jsons");
            // now I have all JSONs in an array
            analyse(context, results, function(result) {
                callback(result);
            })
        }
    });
}

function analyse(context, results) {
    var editArr = [];
    for (i = 0; i < results.length; i++) {
        var arr = [];
        var loopPhotos = checkPhotos(context, results[i].photos);
        var loopVideos = checkVideos(context, results[i].videos);
        Promise.all([loopPhotos, checkVideos]).then(function(result) {
            if (result[0].length > 0) {
                context.log('photos expired')
                arr.push('photo');
            }
            if (result[1].length > 0) {
                context.log('videos expired')
                arr.push('video');
            }
            if (arr.length > 0) {
                editArr.push(results[i].id);
            }
        });
    }
    return Promise.all(editArr);
}

function checkPhotos(context, photos) {
    var arr = [];
    for (i = 0; i < photos.length; i++) {
        var link = photos[i].latestUrl;
        request(link, function(error, response, body) {

            if (response.statusCode == 403) {
                arr.push("photo: " + body);
            }

        });
    }
    return Promise.all(arr);
}

function checkVideos(context, videos) {
    var arr = [];

    context.log(videos)
    for (i = 0; i < videos.length; i++) {
        var link = videos[i].latestUrl;
        request(link, function(error, response, body) {
            if (response.statusCode == 403) {
                arr.push("video: " + body);
            }

        });
    }
    return Promise.all(arr);
}
function createContainer(context, jsons) {
    //code
}
回答如下:

这是checkPhotos()checkVideos()的固定版本:

const rp = require('request-promise');

// returns promise that resolves to an array of 403 messages
// urls that don't respond with 403 don't put anything in the array
function checkUrls(context, urls, msg) {
    const promises = urls.map(item => {
        return rp({
          uri: item.latestUrl, 
          simple: false, 
          resolveWithFullResponse: true}
        ).then(response => {
            if (response.statusCode == 403) {
                return msg + response.body;
            } else {
                return null;
            }
        });
    });

    return Promise.all(promises).then(data => {
        // remove null results from array
        return data.filter(item => item !== null);
    });
}

// returns promise that resolves to an array
function checkPhotos(context, photos) {
    return checkUrls(context, photos, "photo: ");
}

// returns promise that resolves to an array
function checkVideos(context, videos) {
    return checkUrls(context, photos, "video: ");
}

这是一般的想法:

  1. 创建一个共享函数,因为checkPhotos()checkVideos()几乎都在做同样的事情。
  2. 使用request-promise而不是request模块,因为它返回一个promise,这样可以更容易地协调多个异步操作。
  3. 配置request-promise以返回整个响应对象,以便它可以像使用请求一样使用
  4. 过滤掉不返回403的结果,因为如果请求状态为403,原始代码只会在结果数组中放置一些东西。这对我来说似乎不太安全(就像404那样),但这就是你的原始代码正在做。
  5. 使用.map()轻松生成一系列承诺。
  6. 使用Promise.all()知道什么时候整个承诺都解决了。

附:

  1. 您的分析功能也需要重写。它的逻辑不正确。
  2. Promise.all()希望你传递一个承诺数组的参数。
  3. 你传递了一个context变量,但没有使用它。

如何解决麻烦的for循环和承诺没有异步/等待

我正在努力争取循环和承诺,而不使用async / await(这在我最初运行的azure函数版本上不可用,我还没有将我的所有代码转移到更新的版本)我在json文件上检查我的数据库在每个json中,我想看看2个不同数组中包含的URL是否仍然有效。然后,如果url已过期,我想将该json id推入容器以处理稍后/更新。

目前我正在努力尝试每个json测试2个独立的数组。

module.exports = function(context, req) {
    getJsons(context, function(res) {
        createContainer(context, res)
    });
}

function getJsons(context, callback) {
    context.log('start');
    client.queryDocuments(
        collectionUrlJsons,
        `SELECT * FROM r`
    ).toArray((err, results) => {
        if (err) {
            context.log(err);
            context.done();
        } else {
            context.log(results.length + " jsons");
            // now I have all JSONs in an array
            analyse(context, results, function(result) {
                callback(result);
            })
        }
    });
}

function analyse(context, results) {
    var editArr = [];
    for (i = 0; i < results.length; i++) {
        var arr = [];
        var loopPhotos = checkPhotos(context, results[i].photos);
        var loopVideos = checkVideos(context, results[i].videos);
        Promise.all([loopPhotos, checkVideos]).then(function(result) {
            if (result[0].length > 0) {
                context.log('photos expired')
                arr.push('photo');
            }
            if (result[1].length > 0) {
                context.log('videos expired')
                arr.push('video');
            }
        });
        if (arr.length > 0) {
            editArr.push(results[i].id);
        }
    }
    return Promise.all(editArr);
}

function checkPhotos(context, photos) {
    var arr = [];
    for (i = 0; i < photos.length; i++) {
        var link = photos[i].latestUrl;
        request(link, function(error, response, body) {

            if (response.statusCode == 403) {
                arr.push("photo: " + body);
            }

        });
    }
    return Promise.all(arr);
}

function checkVideos(context, videos) {
    var arr = [];

    context.log(videos)
    for (i = 0; i < videos.length; i++) {
        var link = videos[i].latestUrl;
        request(link, function(error, response, body) {
            if (response.statusCode == 403) {
                arr.push("video: " + body);
            }

        });
    }
    return Promise.all(arr);
}
function createContainer(context, jsons) {
    //code
}

编辑下面反映评论 - 将if (arr.length >0)放入Promise.allfunction analyse

module.exports = function(context, req) {
    getJsons(context, function(res) {
        createContainer(context, res)
    });
}

function getJsons(context, callback) {
    context.log('start');
    client.queryDocuments(
        collectionUrlJsons,
        `SELECT * FROM r`
    ).toArray((err, results) => {
        if (err) {
            context.log(err);
            context.done();
        } else {
            context.log(results.length + " jsons");
            // now I have all JSONs in an array
            analyse(context, results, function(result) {
                callback(result);
            })
        }
    });
}

function analyse(context, results) {
    var editArr = [];
    for (i = 0; i < results.length; i++) {
        var arr = [];
        var loopPhotos = checkPhotos(context, results[i].photos);
        var loopVideos = checkVideos(context, results[i].videos);
        Promise.all([loopPhotos, checkVideos]).then(function(result) {
            if (result[0].length > 0) {
                context.log('photos expired')
                arr.push('photo');
            }
            if (result[1].length > 0) {
                context.log('videos expired')
                arr.push('video');
            }
            if (arr.length > 0) {
                editArr.push(results[i].id);
            }
        });
    }
    return Promise.all(editArr);
}

function checkPhotos(context, photos) {
    var arr = [];
    for (i = 0; i < photos.length; i++) {
        var link = photos[i].latestUrl;
        request(link, function(error, response, body) {

            if (response.statusCode == 403) {
                arr.push("photo: " + body);
            }

        });
    }
    return Promise.all(arr);
}

function checkVideos(context, videos) {
    var arr = [];

    context.log(videos)
    for (i = 0; i < videos.length; i++) {
        var link = videos[i].latestUrl;
        request(link, function(error, response, body) {
            if (response.statusCode == 403) {
                arr.push("video: " + body);
            }

        });
    }
    return Promise.all(arr);
}
function createContainer(context, jsons) {
    //code
}
回答如下:

这是checkPhotos()checkVideos()的固定版本:

const rp = require('request-promise');

// returns promise that resolves to an array of 403 messages
// urls that don't respond with 403 don't put anything in the array
function checkUrls(context, urls, msg) {
    const promises = urls.map(item => {
        return rp({
          uri: item.latestUrl, 
          simple: false, 
          resolveWithFullResponse: true}
        ).then(response => {
            if (response.statusCode == 403) {
                return msg + response.body;
            } else {
                return null;
            }
        });
    });

    return Promise.all(promises).then(data => {
        // remove null results from array
        return data.filter(item => item !== null);
    });
}

// returns promise that resolves to an array
function checkPhotos(context, photos) {
    return checkUrls(context, photos, "photo: ");
}

// returns promise that resolves to an array
function checkVideos(context, videos) {
    return checkUrls(context, photos, "video: ");
}

这是一般的想法:

  1. 创建一个共享函数,因为checkPhotos()checkVideos()几乎都在做同样的事情。
  2. 使用request-promise而不是request模块,因为它返回一个promise,这样可以更容易地协调多个异步操作。
  3. 配置request-promise以返回整个响应对象,以便它可以像使用请求一样使用
  4. 过滤掉不返回403的结果,因为如果请求状态为403,原始代码只会在结果数组中放置一些东西。这对我来说似乎不太安全(就像404那样),但这就是你的原始代码正在做。
  5. 使用.map()轻松生成一系列承诺。
  6. 使用Promise.all()知道什么时候整个承诺都解决了。

附:

  1. 您的分析功能也需要重写。它的逻辑不正确。
  2. Promise.all()希望你传递一个承诺数组的参数。
  3. 你传递了一个context变量,但没有使用它。
发布评论

评论列表 (0)

  1. 暂无评论