gpt4 book ai didi

javascript - 将 promise 包装到 Sync 函数中

转载 作者:行者123 更新时间:2023-12-02 04:53:11 25 4
gpt4 key购买 nike

我正在编写一个 Node CLI,其中同步行为通常比异步行为更合适,我希望能够利用以下约定:

 # Write functional code as an async function which returns a Promise
function foobar() { ... }
# Uses async function but blocks on promise fulfillments
function foobarSync() { ... }

例如——使用 RSVP promise 实现——我编写了以下用于调用 shell 脚本的异步函数:

var shell = function (params,options) {
options = extend({timeout: 4000},options);
var commandResponse = '';
var errorMessage ='';
// resolve with a promise
return new RSVP.Promise(function(resolve,reject) {
var spawn = require('child_process').spawn;
var timeout = setTimeout(function() {
reject(new Error('Timed out')); // fulfil promise
}, options.timeout);
try {
var shellCommand = spawn(params.shift(),params);
} catch (err) {
clearTimeout(timeout);
reject(err); // fulfil promise
}
shellCommand.stdout.setEncoding('utf8');
shellCommand.stderr.setEncoding('utf8');
shellCommand.stdout.on('data', function (data) {
commandResponse = commandResponse + data;
});
shellCommand.stderr.on('data', function (data) {
errorMessage = errorMessage + data;
});
shellCommand.on('close', function (code) {
if(code !== 0) {
clearTimeout(timeout);
reject({code:code, message:errorMessage}); // fulfil promise
} else {
clearTimeout(timeout);
resolve(commandResponse); // fulfil promise
}
});
});
};

这行得通,现在我想同步制作:

 # Works
shell(['ls','-l']).then( function (results) {
console.log('Result was: %s', results);
});
# Would like to see work
var results = shellSync(['ls','-l']);

我认为适用于 shellSync 的是:

var shellSync = function (params,options) {
options = extend({pollingInterval: 100},options);
var shellResults = null;
shell(params,options).then(
function(results) {
console.log('Results: %s', results);
shellResults = results;
// return results;
},
function(err) {
console.log('Error: %s', err);
shellResults = err;
// return err;
}
);

while(!shellResults) {
// wait until a Promise is returned or broken (and sets the shellResults variable)
}
return shellResults;
};

不幸的是,它只是运行,永远不会返回。我虽然也许我会实现一个轮询间隔来执行条件语句而不是 while 循环:

    var polling = setInterval(function() {
// return once shellResults is set;
// this setting takes place when either a resolve() or reject()
// is called in Promise
if(shellResults) {
console.log('results are available');
clearInterval(polling);
return shellResults;
}
},options.pollingInterval);

while(1) {
// wait
}

当然,删除 while 循环会导致函数立即返回(带有尚未实现的 promise )。因此,我尝试将 while 循环的“等待”功能与实现的轮询频率结合起来

最佳答案

如果您希望内部代码同步,最简单的方法是在您的内部代码上使用同步 API,但您希望将异步代码包装为同步,对吧?

我认为这可以使用 fibers ( https://www.npmjs.org/package/fibers ) 来实现,或者更具体地说,futures,一个小例子

var Future = require("fibers/future");

// async API, will be wrapped by syncFoo
var asyncFoo = function(cb) {
setTimeout(function() {
cb("foo");
}, 1500);
};

var syncFoo = function() {
var future = new Future();
console.log("asyncFoo will be called");
asyncFoo(function(x) {
future.return(x);
});
console.log("asyncFoo ended");
return future.wait();
};

(function() {
console.log("* Syncfoo will be called");
syncFoo();
console.log("* Syncfoo ended");

console.log("* Syncfoo will be called again");
syncFoo();
console.log("* Syncfoo ended again");

}).future()();

更具体的代码:


var shellSync = function(params, options) {
var future = new Future();

options = extend({pollingInterval: 100},options);
var shellResults = null;
shell(params,options).then(
function(results) {
console.log('Results: %s', results);
future.return({results: results});
},
function(err) {
console.log('Error: %s', err);
future.return({err: err});
}
);

var ret = future.wait();
if (ret.err) {
throw ret.err;
} else {
return ret.results;
}
};

编辑注意:您应该将所有内容包装在 (function() {...}).future()(); 中在光纤上运行它

关于javascript - 将 promise 包装到 Sync 函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25855677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com