Вы не можете вернуть из асинхронных функций ; по крайней мере, не так, как ты.
let posts = []
// ...
for(var i = 0; i < user.friends.length; i++){
// ...
User.findOne(query, function(err, theuser){
// nothing here happens before `return posts` is called below
})
}
return posts;
Это должно помочь вам вернуться на правильный путь -
// reverse copy of user posts
const posts =
[ ...user.posts ].reverse()
// "promisified" findOne
const findOne = query =>
User.findOne
( query
, (err, res) =>
err
? Promise.reject(err)
: Promise.resolve(res)
)
Promise
.all(user.friends.map(username => findOne({ username }))
.map(friend => friend.posts.reverse())
.then(friendPosts => posts.concat(friendPosts)
.then
( allPosts =>
// do something with all posts here
)
Альтернатива - async
/ await
. Здесь мы также используем util.promisify
вместо переписывания findOne
от руки -
const { promisify } =
require('util')
const findOne =
promisify(User.findOne)
// below, `async` functions always return a promise
const allPostsAndFriendsPosts = async (user) =>
{ // write normal synchronous code here
let res =
[ ...user.posts ].reverse()
// inside async functions, we can `await` a promise
const friends =
await Promise.all(user.friends.map(username => findOne({ username }))
// then use the promised value synchronously
for (const f of friends)
res = res.concat(f.posts.reverse())
return res // <-- returns a promise
}
allPostsAndFriendsPosts(user)
.then
( allPosts =>
// do something with all posts
)
async
и await
- тандемный дуэт этой эпохи. Я просто хочу дать оценку их объединенных возможностей. Допустим, у вас есть база данных -
const DB =
{ '/0': { a: 'a', _link: '/1' }
, '/1': { b: 'b', _link: '/2' }
, '/2': { c: 'c', d: 'd', _link: '/3' }
, '/3': { e: 'e' }
, '/4': { f: 'f', _link: '/5' }
, '/5': { g: 'g' }
// ...
}
, где каждый узел имеет путь, например /0
, /1
и т. Д., И узлы могут связываться с другими узлами с помощью свойства _link
. Цепочки link-> link-> link не ограничены по длине. Учитывая начальный узел, цель состоит в том, чтобы создать всю последовательность узлов -
recursiveGet ('/0') .then (console.log, console.error)
// [ { a: 'a' }, { b: 'b' }, { c: 'c', d: 'd' }, { e: 'e' } ]
recursiveGet ('/4') .then (console.log, console.error)
// [ { f: 'f' }, { g: 'g' } ]
recursiveGet ('/99') .then (console.log, console.error)
// Error: path not found: /99
Нам нужен какой-то способ определить цикл , каким-то образом инициализировать это какой-то способ сделать следующий цикл и, наконец, какой-то способ сказать, когда цикл завершен . Ох, и все должно быть асинхронно.
Это сложный заказ, но async
и await
подходят для этой задачи. При написании универсальных функций мы сохраняем как можно более универсальные вещи, чтобы максимизировать возможность повторного использования -
const asyncUnfold = async (loop, init) =>
// call the user's loop with
loop
// the "next" function
// accepts two arguments
// 1. the item to add to the result
// 2. the next accumulator
( async (x, acc) =>
// the item is prepended to the recursive result
[ x, ...await asyncUnfold (f, acc) ]
// the "done" function
// accepts one argument
// 1. then final item of the result
, async (x) => [ x ]
// initial accumulator
, init
)
Учитывая функцию get
, которая не выполняет рекурсивный запрос -
[116 ]
Теперь мы можем написать recursiveGet
, используя asyncUnfold
-
const recursiveGet = async (initUrl) =>
// use our new magic wand
asyncUnfold
// our loop
// receives 3 arguments
// 1. the "next" function
// 2. the "done" function
// 3. the accumulator
( async (next, done, { _link, ...res }) =>
// if we have a _link ...
_link
// add res to the output
// the next step is get(_link)
? next (res, await get (_link))
// otherwise there is no _link
// call done with the last result
: done (res)
// initial accumulator
, await get (initUrl)
)
И все без необходимости касаться Promise
, reject
, resolve
или then
. Я надеюсь, что это дает вам представление о способных выражениях, которые могут быть сделаны с использованием async
и await
. Проверьте результаты в вашем браузере ниже -
const asyncUnfold = async (f, init) =>
f ( async (x, acc) => [ x, ...await asyncUnfold (f, acc) ]
, async (x) => [ x ]
, init
)
const get = async (url = '') =>
fetch (url) .then (res => res .json ())
const recursiveGet = async (initUrl) =>
asyncUnfold
( async (next, done, { _link, ...res }) =>
_link
? next (res, await get (_link))
: done (res)
, await get (initUrl)
)
const DB =
{ '/0': { a: 'a', _link: '/1' }
, '/1': { b: 'b', _link: '/2' }
, '/2': { c: 'c', d: 'd', _link: '/3' }
, '/3': { e: 'e' }
, '/4': { f: 'f', _link: '/5' }
, '/5': { g: 'g' }
}
// fake fetch for demo
const fetch = (url = '') =>
DB[url] === undefined
? Promise .reject (Error(`path not found: ${url}`)) .then (delay)
: Promise .resolve ({ json: () => DB[url] }) .then (delay)
// fake delay for demo
const delay = (x, ms = 250) =>
new Promise (r => setTimeout (r, ms, x))
recursiveGet ('/0') .then (console.log, console.error)
// [ { a: 'a' }, { b: 'b' }, { c: 'c', d: 'd' }, { e: 'e' } ]
Для списка всех экранных сессий для пользователя выполните следующую команду как того пользователя:
screen -ls
Для наблюдения всех экранных сессий на определенной машине можно сделать:
ls -laR /var/run/screen/
я получаю это на своей машине:
gentle ~ # ls -laR /var/run/screen/
/var/run/screen/:
total 1
drwxrwxr-x 4 root utmp 96 Mar 1 2005 .
drwxr-xr-x 10 root root 840 Feb 1 03:10 ..
drwx------ 2 josh users 88 Jan 13 11:33 S-josh
drwx------ 2 root root 48 Feb 11 10:50 S-root
/var/run/screen/S-josh:
total 0
drwx------ 2 josh users 88 Jan 13 11:33 .
drwxrwxr-x 4 root utmp 96 Mar 1 2005 ..
prwx------ 1 josh users 0 Feb 11 10:41 12931.pts-0.gentle
/var/run/screen/S-root:
total 0
drwx------ 2 root root 48 Feb 11 10:50 .
drwxrwxr-x 4 root utmp 96 Mar 1 2005 ..
Это скорее блестяще использование Unixy Сокетов Unix, перенесенных в полномочия файловой системы обработать безопасность, состояние и потоки.
Экран команды - список может быть тем, что Вы хотите.
Посмотрите человек
Я не действительно уверен в Вашем вопросе, но если все, что Вы действительно хотите, является списком, в настоящее время открывал экранную сессию, попробуйте:
screen -ls
Несколько человек уже указали, что
$ screen -ls
перечислил бы экранные сессии.
Вот другой прием, который может быть полезен для Вас.
, Если Вы добавляете следующую команду как последнюю строку в Вашем файл .bashrc на сервере xxx, затем это автоматически снова соединится с Вашей экранной сессией на входе в систему.
screen -d -r
Hope Вы находите это полезным.
Таким образом, Вы используете экран для поддерживания экспериментов в рабочем состоянии в фоновом режиме, или что? Если так, почему не только запускают его в фоновом режиме?
./experiment &
И если Вы спрашиваете, как получить уведомление задание я сделанный, как насчет того, чтобы представить эксперимент в виде строки вместе с почтовой командой?
./experiment && echo "the deed is done" | mail youruser@yourlocalworkstation -s "job on server $HOSTNAME is done"
Хотя ответ Джошперри правильный, меня очень раздражает, что он не сообщает вам имя экрана (тот, который вы установили с опцией -t), который на самом деле используется для идентификации сеанса. (конечно, не его вина, это недостаток экрана)
Вот почему вместо этого я использую такой скрипт: ps auxw|grep -i screen|grep -v grep