具有不同超时的同步回调

时间:2019-08-05 12:57:00

标签: javascript node.js asynchronous settimeout

我正在尝试使用回调函数进行控制台,该回调函数本身是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}]

3 个答案:

答案 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);
});