How do I resolve individual promise from a central

2020-04-08 14:50发布

I have an event listener, which will receive event (from server) whenever a specific task is done. I desire each task to be encapsulated in a promise, so that I can construct complex ordered workflow in a clean manner.

How would I resolve each task promise (by id) from a global listener? Here's an conceptual example of what I am trying to achieve.

// list of all tasks
var tasks = {}
tasks['id-1'] = getTask('id-1')
tasks['id-2'] = getTask('id-2')

// do task in order
// each task will issue request to server, and wait for reply 
tasks['id-1'].startPromise()
  .then(function(result) {

    // start second task from first task's data
    return tasks['id-2'].startPromise(result);
  })
  .then(function() {
    // finalized task works
    return true;
  });


// listen to task finish
client.listen('onReceive', function(event) {
  if(event.is('taskFinished')) {
    var id = event.taskId;
    tasks[id].resolve(event.result); //How do I resolve task from listener??
  }
});

1条回答
在下西门庆
2楼-- · 2020-04-08 15:39

Yes, you'd need a global mapping from ids to resolver functions.

const tasks = new Map;
function runTask(id, data) {
    return new Promise(resolve => {
        // if (tasks.has(id)) throw new Error("cannot run multiple "+id+" at once");
        tasks.set(id, resolve);
        client.fire('start', id, data); // or whatever you need to trigger the task
    })
}
client.on('taskFinished', event => { // or however you get notified of finished tasks
    const id = event.taskId;
    if (tasks.has(id)) {
        tasks.get(id)(event.result);
        tasks.delete(id);
    }
});

You can also use a plain object instead of the ES6 Map if you prefer (or need ES5 compatibility), and you might write the listener so that it is only active when the mapping is not empty.

You would use this like

runTask('id-1').then(result =>
    runTask('id-2', result)
).then(() => {
    console.log("both done");
    return true;
})
查看更多
登录 后发表回答