Ожидание результата обратного вызова перед уменьшением

#javascript #node.js #asynchronous

Вопрос:

Я хотел бы знать, смогу ли я с этим справиться setTimeout . Функция together должна принимать funcs то, что представляет собой список асинхронных функций, а также а pred и n в. Каждая из функций должна вызывать callback функцию, которая должна возвращать либо значение, либо ошибку. Это работает , если я удаляю setTimeout и оставляю только return cb(...) , но я хотел бы setTimeout сделать это перед вызовом callback в каждой функции. Он together должен возвращать массив результатов , которые были приняты pred , например, если pred > 10 results они содержат только значения, превышающие 10.

Мой код:

 function fun1(value,cb) {
    if ((value * 100) > 400)  {
        return setTimeout(() => cb(null, value*100), 2000)
    }
    else {
      return cb(new Error("error"))
    }
}
function fun2(value,cb) {
    if ((value * 20) > 50)  {
        return setTimeout(() => cb(null, value*20), 2000)
    }
    else {
      return cb(new Error("error"))
    }
}

function fun3(value,cb) {
    if ((value -30 ) > 0)  {
      return setTimeout(() => cb(null, value-30), 2000)
    }
    else {
      return cb(new Error("error"))
    }
}
function callback(err, wyn) {
    if (err) {
        console.log(err)
    }
    else {
        return wyn
    }


}
//console.log(fun1(1000,callback))

const together = (funcs, pred) => (n) => {
    let results = []
    funcs.reduce((prev,curr) => {
        if (curr(n,callback) > pred) {
            results.push(curr(n,callback))
        }

    }, 0)
    return results
};

console.log(together([fun1,fun2,fun3], 5)(10))
 

Ответ №1:

Вы должны использовать Promises и Promises.all получать значения этих обещаний. Вы можете использовать then/catch или async/await .

 function fun1(value,cb) {
   return new Promise ((res, rej) => {
      if ((value * 100) > 400)  {
        return  setTimeout(() => res(cb(null, value*100)), 2000);
    }
    else {
      rej(cb(new Error("error")));
    }
   })
   
}
function fun2(value,cb) {
    return new Promise ((res, rej) => {
      if ((value * 20) > 50)  {
        setTimeout(() => res(cb(null, value*20)), 2000);
    }
    else {
      rej(cb(new Error("error")))
    }
   })
   
}

function fun3(value,cb) {
   return new Promise ((res, rej) => {
      if ((value -30 ) > 0)  {
      setTimeout(() => res(cb(null, value-30)), 2000)
    }
    else {
      rej(cb(new Error("error")));
    }
   })
    
}
function callback(err, wyn) {
    if (err) {
        console.log(err)
    }
    else {
        return wyn
    }


}
//console.log(fun1(1000,callback))

const together = (funcs, pred) => (n) => {
    let results = []
    funcs.forEach((func) => {
            results.push(curr(n,callback))
       
    })
    // if any of your callback returns rejection it will not give values
    Promise.all(results).then(values => { 
     //values will be an array
    console.log(values[0])
   }).catch(console.log);
};

console.log(together([fun1,fun2,fun3], 5)(10))

 

Вместо использования reduce, use forEach или for циклов проверьте, когда следует использовать метод reduce.

Комментарии:

1. Если это сработает для вас, вы можете принять ответ, который даст очки обоим. Спасибо!

2. Кстати. почему я не могу использовать reduce здесь? Что, если бы я хотел использовать reduce?

3. Что я мог бы сделать,чтобы сделать это forEach , если (функция(n, обратный вызов) > пред)? это не работает

4. Поскольку вы, конечно, асинхронны по своей природе. Вы можете выполнить синхронный вызов, поскольку ваши последующие запросы основаны на значениях cb, а циклы for всегда синхронизированы по своей природе.

5. Да, вам, возможно, потребуется обработать это с помощью оболочки и сгенерированного пользовательского сообщения об ошибке. Кроме того, если вы хотите запускать функцию последовательно, вам необходимо использовать функции генератора.