Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 承诺对某些回调具有优先级的回调队列_Javascript_Node.js_Promise_Priority Queue - Fatal编程技术网

Javascript 承诺对某些回调具有优先级的回调队列

Javascript 承诺对某些回调具有优先级的回调队列,javascript,node.js,promise,priority-queue,Javascript,Node.js,Promise,Priority Queue,我的代码需要同时执行大量异步操作,并以特定的顺序方式处理它们的承诺 我所说的“特定顺序方式”的意思是,假设你按照这个顺序开始允诺,promise1,promise2,promise3,而promise3实际上首先解析,然后是promise2秒,那么我想要的是处理promise3,promise2和promise1按顺序依次 让我们考虑一个超时异步函数,在X秒后超时,以及 FojMyItEM1, FojMyItMe2,它返回承诺,当满足时,应该执行一个不同的代码,这取决于 TimeOuts< /C

我的代码需要同时执行大量异步操作,并以特定的顺序方式处理它们的承诺

我所说的“特定顺序方式”的意思是,假设你按照这个顺序开始允诺,
promise1
promise2
promise3
,而promise3实际上首先解析,然后是promise2秒,那么我想要的是处理
promise3
promise2
promise1
按顺序依次

让我们考虑一个<代码>超时异步函数,在X秒后超时,以及<代码> FojMyItEM1,<代码> FojMyItMe2<代码>,它返回承诺,当满足时,应该执行一个不同的代码,这取决于<代码> TimeOuts< /C>是否已解决。< /P> 在一个具体的场景中,假设有一位顾客在柜台等待一件物品的交付,要么顾客留下来,我们可以一次带一件物品直接在柜台为他服务,要么顾客离开(

timeout
),我们必须请服务员来,这样当物品到达时,他/她可以将物品带给他。请注意,即使在交付一个项目时,其他项目仍应进行交付(承诺待定),甚至可能在向客户提供一个项目或服务器到达时到达(履行)

下面是一些代码

const allItemsToBeDeliveredPromises = [fetchMyItem1(), fetchMyItem2(), ...]
const customerLeavesCounterPromise = timeout()

const waiter = undefined

const allPromisesToBeFulfilled = [...allItemsToBeDeliveredPromises, customerLeavesCounterPromise]

// LOOP
const itemDeliveredOrVisitorLeft = await Promise.all(allPromisesToBeFulfilled)

if hasCustomerLeft(itemDeliveredOrCustomerLeft) {
  // hasCustomerLeft allows us to detect if the promise that resolved first is `customerLeavesCounterPromise` or not
  waiter = await callWaiter()
} else {
  // An item has arrived
  if (waiter) {
    deliverItemViaWaiter(itemDeliveredOrVisitorLeft)
  } else {
    deliverItemAtCounter(itemDeliveredOrVisitorLeft)
  }
}
// remove itemDeliveredOrCustomerLeft from allPromisesToBeFulfilled

// END loop
我不知道如何为这个场景实现循环。承诺在解析时必须累积到队列中,但队列中的特定承诺具有优先级(超时承诺应在到达时尽快执行,但如果已在处理承诺履行,则应在完成当前承诺的处理后执行)

其中一项承诺必须具有这样的效果,即无论何时履行,它都应该改变对其他尚未履行或尚未履行的承诺的处理

你把它们都放在一起吗?比如:

promise1 = asyncFunc1()
promise2 = asyncFunc2()
promise3 = asyncFunc3()

Promise.all([promise1, promise2, promise3]).then(//sometthing)
如果是,则无法执行,除非promise2函数和promise3函数没有等待promise1函数处理的事件、锁或其他内容

如果是这种情况,最好组织如下承诺:

asyncFunc1()
    .then(() => asyncFunc2(paramIfOk))
    .catch(() => asyncFunc2(paramIfFail))
在您的示例中:

const allItemsToBeDelivered = [myPromise1(), myPromise2(), ...]
myPromise1()代码应该等待项目交付,并检查是否有人在等待它。这是一个模型/代码设计问题,而不是承诺问题

另一种方法是考虑一些事件驱动的逻辑:实体客户有一个侦听器,用于传递事件,它将由WaTiTimeDelimeDead()承诺在解析自身之前启动。 编辑:根据这里的要求,对事件驱动的解决方案进行更多的阐述

简短回答:这在很大程度上取决于您的软件设计

它已经发布并在生产中运行了?对这样的变化要小心。如果您正在开发一项服务,那么您仍然可以及时考虑一些逻辑变化。一个不会从根本上改变工作方式,但使用事件的解决方案并不是那么好,混合模式从长远来看永远不会有回报

例如:

const events = require('events');

class Customer() {

    constructor(shop) {
        this.emitter = new events.EventEmitter()

        this.shopEventListener = shop.emitter
        this.setupEventLinstening() // for keeping things clean in the constructor

        // other properties here
    }

    setupEventLinstening() {
        this.shopEventListener.on('product-delivered', (eventData) => {
            // some logic
        })
    }

    buyProduct() {
        // some logic

        this.emitter.emit('waiting-delivery', eventData)
    }
}

class Shop() {

    constructor(shop) {
        this.emitter = new events.EventEmitter()

        // other properties here
    }

    addCustomer(customer) {
        customer.emitter.on('waiting-delivery', (eventData) => {
            // some logic

            self.waitDelivery().then(() => self.emitter.emit('product-delivered'))
        })
    }

    waitDelivery() {
        return new Promise((resolve, reject) => {
            // some logic

            resolve()
        })
    }
}

// setup
const shop = new Shop()
const customer = new Customer(shop)
shop.addCustomer(customer)
这是一种看待逻辑的新方法,但在承诺中也可以使用类似的方法:

const waitDelivery = () => new Promise((resolve, reject) => {
    logisticWaitDelivery().then(() => {
        someEmitter.emit('item-delivered')
        resolve()
    })
}

const customerPromise = () => new Promise((resolve, reject) => {
    someListener.on('item-delivered', () => {
        resolve()
    })
}

promiseAll([waitDelivery, customerPromise])
其中一项承诺必须具有这样的效果,即无论何时履行,它都应该改变对其他尚未履行或尚未履行的承诺的处理

你把它们都放在一起吗?比如:

promise1 = asyncFunc1()
promise2 = asyncFunc2()
promise3 = asyncFunc3()

Promise.all([promise1, promise2, promise3]).then(//sometthing)
如果是,则无法执行,除非promise2函数和promise3函数没有等待promise1函数处理的事件、锁或其他内容

如果是这种情况,最好组织如下承诺:

asyncFunc1()
    .then(() => asyncFunc2(paramIfOk))
    .catch(() => asyncFunc2(paramIfFail))
在您的示例中:

const allItemsToBeDelivered = [myPromise1(), myPromise2(), ...]
myPromise1()代码应该等待项目交付,并检查是否有人在等待它。这是一个模型/代码设计问题,而不是承诺问题

另一种方法是考虑一些事件驱动的逻辑:实体客户有一个侦听器,用于传递事件,它将由WaTiTimeDelimeDead()承诺在解析自身之前启动。 编辑:根据这里的要求,对事件驱动的解决方案进行更多的阐述

简短回答:这在很大程度上取决于您的软件设计

它已经发布并在生产中运行了?对这样的变化要小心。如果您正在开发一项服务,那么您仍然可以及时考虑一些逻辑变化。一个不会从根本上改变工作方式,但使用事件的解决方案并不是那么好,混合模式从长远来看永远不会有回报

例如:

const events = require('events');

class Customer() {

    constructor(shop) {
        this.emitter = new events.EventEmitter()

        this.shopEventListener = shop.emitter
        this.setupEventLinstening() // for keeping things clean in the constructor

        // other properties here
    }

    setupEventLinstening() {
        this.shopEventListener.on('product-delivered', (eventData) => {
            // some logic
        })
    }

    buyProduct() {
        // some logic

        this.emitter.emit('waiting-delivery', eventData)
    }
}

class Shop() {

    constructor(shop) {
        this.emitter = new events.EventEmitter()

        // other properties here
    }

    addCustomer(customer) {
        customer.emitter.on('waiting-delivery', (eventData) => {
            // some logic

            self.waitDelivery().then(() => self.emitter.emit('product-delivered'))
        })
    }

    waitDelivery() {
        return new Promise((resolve, reject) => {
            // some logic

            resolve()
        })
    }
}

// setup
const shop = new Shop()
const customer = new Customer(shop)
shop.addCustomer(customer)
这是一种看待逻辑的新方法,但在承诺中也可以使用类似的方法:

const waitDelivery = () => new Promise((resolve, reject) => {
    logisticWaitDelivery().then(() => {
        someEmitter.emit('item-delivered')
        resolve()
    })
}

const customerPromise = () => new Promise((resolve, reject) => {
    someListener.on('item-delivered', () => {
        resolve()
    })
}

promiseAll([waitDelivery, customerPromise])

排两个队,第一个队结束后第二个队开始:

var highPriority=[ph1,ph2,...]//promises that have to be executed first
var lowPriority=[pl1,pl2,...]//promises that have to wait the high priority promises
Promise.all(highPriority).then(()=>{
    Promise.all(lowPriority)
})

排两个队,第一个队结束后第二个队开始:

var highPriority=[ph1,ph2,...]//promises that have to be executed first
var lowPriority=[pl1,pl2,...]//promises that have to wait the high priority promises
Promise.all(highPriority).then(()=>{
    Promise.all(lowPriority)
})
我的代码需要同时执行大量异步操作,并以特定的顺序方式处理它们的承诺

您可以使用流来使用承诺,因为流本质上是一次处理一条消息的队列

想法(即未经测试):

编辑:事实上,我们希望在承诺解决时按顺序处理承诺(即,所有承诺的单个后期处理)
让customerhasleet=false;
timeout()//您的代码。。。
.然后(()=>{customerhasleet=true;});/。。。布尔型
const allItemsToBeDeliveredPromises=[fetchMyItem1(),fetchMyItem2(),…];
const postprocessain=Promise.resolve();//从一个准备好兑现的承诺开始
//在每个承诺中添加下一步,以便一个承诺一旦解决,它就会注册
//作为后处理链的下一步
forEach(p=>p.then(order=>postProcessChain.then(async()=>{
//执行可能与结果顺序异步的操作,如:
如果(customerHasLeft){/*查找wai