Javascript 和异步问题(使用 yandex 地图构建距离矩阵 api)
Javascript and async problem (building distance matrix with yandex maps api)
我是 js 和 async/await 的新手,我想使用 yandex 地图 api 构建距离矩阵,然后使用 ACO 算法优化路线。
一切正常,但由于等待循环中的每个请求,我的距离矩阵生成了这么长的时间。我知道我应该避免它,但我不知道该怎么做。
我的距离矩阵应该在调用ACO算法函数之前完成。
async function buildDistanceMatrix(ymaps) {
const n = routeCoords.length;
let distanceMatrix = [];
console.log(routeCoordsRef.current);
for (let i = 0; i < n; i++) {
let newArr = [];
for (let j = 0; j < n; j++) {
await ymaps.route([routeCoordsRef.current[i], routeCoords[j]]).then((route) => {
newArr.push(route.getLength())
console.log(i, j, routeCoordsRef.current[i], routeCoords[j], route.getLength());
});
}
distanceMatrix.push(newArr);
}
return distanceMatrix;
}
let distanceMatrix = await buildDistanceMatrix(ymaps);
// and here my distance matrix done and i'm calling another function that uses distanceMatrix
我认为您需要考虑以下两个注意事项...
注意 1: 通常在处理 promise 时,要么使用“async”/“await”,要么坚持使用“.then()”语法,但不要混用他们。例如...
async function buildDistanceMatrix(ymaps) {...
let route = await ymaps.route( [ routeCoordsRef.current[ i ], routeCoords[ j ] ] );
newArr.push( route.getLength() );
console.log( i, j, routeCoordsRef.current[ i ], routeCoords[ j ], route.getLength() );
...}
...或...
function buildDistanceMatrix(ymaps) {...
ymaps.route( [ routeCoordsRef.current[ i ], routeCoords[ j ] ] ).then( ( route ) => {
newArr.push( route.getLength() );
console.log( i, j, routeCoordsRef.current[ i ], routeCoords[ j ], route.getLength() );
} );
...}
一般来说,“async”/“await”更具可读性,因为它提供了一种按程序阅读的语法,有助于避免 then()
函数的嵌套地狱。
注 2: Yandex 路由器功能似乎使用了 Web 服务...
...因此需要 promise,因为 javascript 代码基本上暂停等待 Yandex 服务器响应后解决的 promise。
建议查看 Promise.all() 函数...
...因为这允许您的函数启动多个承诺而无需等待任何承诺完成,并且只有在创建所有承诺之后您的函数才会等待所有承诺得到解决。
主要好处是远程服务器可以同时处理所有请求。
在 运行 走这条路之前,请检查 Yandex 服务条款以确定是否对并发未完成呼叫的数量有限制。此外,设计良好的 Web 服务会限制并发请求的数量,因此对于少量 Web 调用可能会在性能上有一些较大的提升,但在一定限制之后,Web 服务器会开始节流,然后调用基本上会排队(或忽略!)并再次同步处理...
编辑:使用 Promise.all 和 async / await 语法。
简而言之,您的函数在创建承诺时不应等待,而应将承诺捕获到数组中。然后,一旦创建了所有承诺(在本例中,启动了一系列 Web 服务调用),然后在 Promise.all()
函数上等待,传递所有未解决的承诺。结果数组将直接对应于承诺在 Promise.all()
中传递的顺序。以下是您的函数的大致外观。请注意添加了 parallelArray,这是一种捕获您以后使用 arrayOfResults 时需要的任何辅助数据的方法...
async function buildDistanceMatrix(ymaps) {...
let arrayOfPromises = [];
let parallelArray = [];
for ( let i = 0; i < n; i++ ) {
for (let j = 0; j < n; j++ ) {
arrayOfPromises.push( ymaps.route( [ routeCoordsRef.current[ i ], routeCoords[ j ] ] ) );
parallelArray.push( { i: i, j: j, rci: routeCoordsRef.current[ i ], rcj: routeCoords[ j ] );
}
}
let arrayOfResults = await Promise.all( arrayOfPromises );
...}
希望这对您有所帮助...
我是 js 和 async/await 的新手,我想使用 yandex 地图 api 构建距离矩阵,然后使用 ACO 算法优化路线。 一切正常,但由于等待循环中的每个请求,我的距离矩阵生成了这么长的时间。我知道我应该避免它,但我不知道该怎么做。
我的距离矩阵应该在调用ACO算法函数之前完成。
async function buildDistanceMatrix(ymaps) {
const n = routeCoords.length;
let distanceMatrix = [];
console.log(routeCoordsRef.current);
for (let i = 0; i < n; i++) {
let newArr = [];
for (let j = 0; j < n; j++) {
await ymaps.route([routeCoordsRef.current[i], routeCoords[j]]).then((route) => {
newArr.push(route.getLength())
console.log(i, j, routeCoordsRef.current[i], routeCoords[j], route.getLength());
});
}
distanceMatrix.push(newArr);
}
return distanceMatrix;
}
let distanceMatrix = await buildDistanceMatrix(ymaps);
// and here my distance matrix done and i'm calling another function that uses distanceMatrix
我认为您需要考虑以下两个注意事项...
注意 1: 通常在处理 promise 时,要么使用“async”/“await”,要么坚持使用“.then()”语法,但不要混用他们。例如...
async function buildDistanceMatrix(ymaps) {...
let route = await ymaps.route( [ routeCoordsRef.current[ i ], routeCoords[ j ] ] );
newArr.push( route.getLength() );
console.log( i, j, routeCoordsRef.current[ i ], routeCoords[ j ], route.getLength() );
...}
...或...
function buildDistanceMatrix(ymaps) {...
ymaps.route( [ routeCoordsRef.current[ i ], routeCoords[ j ] ] ).then( ( route ) => {
newArr.push( route.getLength() );
console.log( i, j, routeCoordsRef.current[ i ], routeCoords[ j ], route.getLength() );
} );
...}
一般来说,“async”/“await”更具可读性,因为它提供了一种按程序阅读的语法,有助于避免 then()
函数的嵌套地狱。
注 2: Yandex 路由器功能似乎使用了 Web 服务...
...因此需要 promise,因为 javascript 代码基本上暂停等待 Yandex 服务器响应后解决的 promise。
建议查看 Promise.all() 函数...
...因为这允许您的函数启动多个承诺而无需等待任何承诺完成,并且只有在创建所有承诺之后您的函数才会等待所有承诺得到解决。
主要好处是远程服务器可以同时处理所有请求。
在 运行 走这条路之前,请检查 Yandex 服务条款以确定是否对并发未完成呼叫的数量有限制。此外,设计良好的 Web 服务会限制并发请求的数量,因此对于少量 Web 调用可能会在性能上有一些较大的提升,但在一定限制之后,Web 服务器会开始节流,然后调用基本上会排队(或忽略!)并再次同步处理...
编辑:使用 Promise.all 和 async / await 语法。
简而言之,您的函数在创建承诺时不应等待,而应将承诺捕获到数组中。然后,一旦创建了所有承诺(在本例中,启动了一系列 Web 服务调用),然后在 Promise.all()
函数上等待,传递所有未解决的承诺。结果数组将直接对应于承诺在 Promise.all()
中传递的顺序。以下是您的函数的大致外观。请注意添加了 parallelArray,这是一种捕获您以后使用 arrayOfResults 时需要的任何辅助数据的方法...
async function buildDistanceMatrix(ymaps) {...
let arrayOfPromises = [];
let parallelArray = [];
for ( let i = 0; i < n; i++ ) {
for (let j = 0; j < n; j++ ) {
arrayOfPromises.push( ymaps.route( [ routeCoordsRef.current[ i ], routeCoords[ j ] ] ) );
parallelArray.push( { i: i, j: j, rci: routeCoordsRef.current[ i ], rcj: routeCoords[ j ] );
}
}
let arrayOfResults = await Promise.all( arrayOfPromises );
...}
希望这对您有所帮助...