我正在尝试使用回调函数进行控制台,该回调函数本身是setTimeout函数内部的回调函数。如何获得有序的结果?
我希望调用f1的回调,然后调用f2,最后调用f3,无论它们的计时器如何。
let f1 = (cb) => {
setTimeout(() => {
cb(null, {a: 1})
},100)
}
let f2 = (cb) => {
setTimeout(() => {
cb(null, {a: 2})
},50)
}
let f3 = (cb) => {
setTimeout(() => {
cb(null, {a: 3})
},10)
}
function parallelConsole(arr, cb) {
let result = [];
arr.forEach(func => {
func((temp, val) => {
console.log(val)
result.push(val)
if(arr.length === result.length) {
cb(result)
}
})
})
}
parallelConsole([f1, f2, f3], (res) => {
console.log(res) //[{a: 3}, {a: 2}, {a: 1}]
})
预期结果:[{a:1},{a:2},{a:3}]
实际结果:[{a:3},{a:2},{a:1}]
答案 0 :(得分:1)
如果确实需要使用回调,并且如果该回调用于与生产相关的项目,是否可以使用async.js?它提供了一些非常有用的功能(.each
可能正是您想要的功能。
我希望调用f1的回调,然后调用f2,最后调用f3,无论它们的计时器如何。
对此我有点困惑。如果存在超时,则将在经过指定时间后调用回调。还是无论调用回调的时间如何,都以有序方式(1、2、3)console.log
进行结果查询?
编辑:我已经修复了一些代码,所以我认为它可以满足您的要求。 promise
的{{1}}未返回。另外,如评论中所指出的那样,使用f1, f2, f3
可以确保在所有的诺言都兑现之后,最终的回调会被调用。
Promise.all
答案 1 :(得分:1)
import cv2
import math
import numpy as np
from cv2.ximgproc import createFastLineDetector
img = cv2.imread('calculate_width.png')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray_img, 150, 255,
cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
sure_bg = cv2.dilate(opening, kernel)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist_transform, 0.3*dist_transform.max(),
255, 0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
lines = createFastLineDetector(_length_threshold=20).detect(unknown)
for cur in lines:
(x1, y1, x2, y2) = cur[0]
dist = math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2))
print("Distance between ({:.2f}, {:.2f}) - ({:.2f}, {:.2f})"
.format(x1, y1, x2, y2))
cv2.line(img, pt1=(x1, y1), pt2=(x2, y2), color=(0, 255, 0),
thickness=2)
cv2.imshow("detected", img)
cv2.waitKey(0)
答案 2 :(得分:0)
如果您愿意全力以赴Promises而不是回调,那么代码会变得更加优雅:
// Promisified delay. Resolves with the given optional value after msec.
const delay = (msec, value) =>
new Promise(resolve => setTimeout(() => resolve(value), msec));
// Call `cb` on the resolved value of `p`; resolve with the same value.
const tapPromise = (p, cb) =>
p.then(v => {
cb(v);
return v;
});
// Factories for the slow promises
const f1 = () => delay(100, { a: 1 });
const f2 = () => delay(50, { a: 2 });
const f3 = () => delay(10, { a: 3 });
// Create three promises and tap them with console.log.
// (They start executing right away, not when they're waited on.)
const promises = [f1(), f2(), f3()].map(p => tapPromise(p, console.log));
// Wait for all three promises to resolve, then log the results.
// Promise.all guarantees the order is the same as with the original promises.
Promise.all(promises).then(results => {
console.log(results);
});